home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 1 / Cream of the Crop 1.iso / PROGRAM / ANIVGA.ARJ / ANIVGA.DOC next >
Text File  |  1991-11-17  |  131KB  |  2,759 lines

  1.        ░░░░░░▄ ░░░▄ ░░▄ ░░░░░░▄                ░░▄ ░░▄  ░░░░▄  ░░░░░░▄
  2.        ░░█▀░░█ ░░░░▄░░█   ░░█▀▀                ░░█ ░░█ ░░█▀▀▀  ░░█▀░░█
  3.        ░░░░░░█ ░░█░░░░█   ░░█      ░░░░░░▄     ░░█ ░░█ ░░█░░░▄ ░░░░░░█
  4.        ░░█▀░░█ ░░█ ░░░█   ░░█       ▀▀▀▀▀▀      ░█ ░█▀ ░░█ ░░█ ░░█▀░░█
  5.        ░░█ ░░█ ░░█  ░░█ ░░░░░░▄                  ░░█▀   ░░░░█▀ ░░█ ░░█
  6.         ▀▀  ▀▀  ▀▀   ▀▀  ▀▀▀▀▀▀                   ▀▀     ▀▀▀▀   ▀▀  ▀▀
  7.  
  8.  
  9.                           ░░░░░▄ ░░░░░░▄ ░░░░▄
  10.                           ░░█▀░░▄░░█▀░░█░░█▀░░▄
  11.                           ░░█ ░░█░░█ ░░█░░█  ▀▀
  12.                           ░░█ ░░█░░█ ░░█░░█ ░░▄
  13.                       ░░▄ ░░░░░█▀░░░░░░█ ░░░░█▀
  14.                        ▀▀  ▀▀▀▀▀  ▀▀▀▀▀▀  ▀▀▀▀
  15.  
  16.                         (English documentation)
  17.  
  18.             ┌─────────────────────────────────────────────┐
  19.             │                   ANIVGA                    │
  20.             │      a Sprite-Unit for TurboPascal V6.0     │
  21.             │              by Kai Rohrbacher              │
  22.             │                 Version 1.0                 │
  23.             └─────────────────────────────────────────────┘
  24.  
  25.  
  26. Purpose  : Animation of sprites on a VGA's 320x200x256 mode and
  27.            TurboPascal V6.0
  28. Author   : Kai Rohrbacher
  29.            Germany
  30.            Internet: S_ROHRBACHER@IRAVCL.IRA.UKA.DE
  31.            FIDO    : 2:241/7503
  32. Language : TurboPascal V6.0
  33. Date     : May 1991
  34.  
  35. ---------------------------------------------------------------------
  36. Always remember: "I know my English spelling is bad, but if I used my
  37.                   own language you probably couldn't read it at all."
  38.                                                      -- Nico de Vries
  39. ---------------------------------------------------------------------
  40.  
  41. 0. Table of contents
  42. ────────────────────
  43.  
  44.   1. Prélude: Legal Notices
  45.   2. What is VGA?
  46.   3. Features and Restrictions of ANIVGA
  47.   4. "HELLO WORLD" - A First Example
  48.   5. How ANIVGA works
  49.   6. Tips, tricks and techniques
  50.   7. Credits
  51.   8. ANIVGA Reference Manual
  52.  
  53.  
  54. 1. Prélude: Legal Notices
  55. ─────────────────────────
  56.  
  57. Okay, the boring stuff first...
  58.  
  59. The author hereby disclaims all warranties relating to this software,
  60. whether expressed or implied, including without limitation any implied
  61. warranties of merchantability or fitness for a particular purpose.
  62. I will not be liable for any special, incidental, consequential, indirect
  63. or similar damages due to loss of data/damage to hardware or any other
  64. reason, even if I have been advised of the possibility of such damages.
  65.  
  66. This programming toolkit is released as "freeware" by the author.
  67. It is however copyrighted and all rights and ownership are kept with the
  68. author. You may use it, copy it and give it to everybody as long as no
  69. modifications are made  -- but don't try to sell it (or part of it)!
  70.  
  71. Nevertheless, all programs you realize with this software package may be
  72. distributed freely - the only thing I ask you for is to mention the use
  73. of this toolkit in your program and to send me a copy of your program.
  74.  
  75.  
  76. 2. What is ANIVGA?
  77. ──────────────────
  78.  
  79. ANIVGA is a powerful toolkit for the animation of sprites on any IBM (or com-
  80. patible) with a VGA card installed.
  81. It consists of one (big) TurboPascal V6.0-unit to be used by your applications
  82. and some utilities to simplify its use:
  83.  
  84. ANIVGA.PAS   - the source code of the animation unit
  85. MAKES.EXE    - a simple spritemaker program (requires a mouse)
  86. GRAB.EXE     - a TSR-program to "grab" sprites from other graphics
  87. UNLIB.EXE    - a utility to break apart a library of sprites back into
  88.                its individual sprite files
  89. DUMP_SPR.EXE - a "sprite dumper" which disassembles a (binary) sprite file into
  90.                an ASCII-text
  91. *.*          - documentation, examples, ...
  92.  
  93. Copy these files into your TurboPascal-directory and compile ANIVGA.PAS to
  94. implement ANIVGA on your system - that's all.
  95.  
  96.  
  97. 3. Features and Restrictions of ANIVGA
  98. ──────────────────────────────────────
  99.  
  100. Some of ANIVGA's features are:
  101.  
  102.  - flickerfree animation by a "page-flipping" algorithm and using the
  103.    vertical retrace signal
  104.  - sprite movement in any increments you want
  105.  - arbitrary background image for the animation
  106.  - full use of the VGA's 256-color mode
  107.  - several sprite display methods available:
  108.    - sprites can be written normally (covering underlying figures)
  109.    - sprites can be declared to be transparent with regard to the background
  110.      or other sprites pixel by pixel
  111.    - sprites can change their color depending on the underlying background
  112.      image (-> shadow function)
  113.  - display methods can be different for each sprite
  114.  - pixel precise hit-detection routine built in
  115.  - correct clipping of sprites at the screen boundaries
  116.  - up to 32767 different sprites
  117.  - up to 500 sprites may be simultaneously active
  118.  - maximal size of each sprite = 64k
  119.  - maximal size of all loaded sprites only restricted by available memory
  120.  - works with virtual coordinates in the range -16000..+16000
  121.  - thus simple creation of horizontal/vertical "scrolling" games
  122.  - scrolling background image, too
  123.  - several supporting routines to: drawing lines (with built in clipping-
  124.    algorithm), points and graphic-text (incl. clipping), automatic heap
  125.    management for loading of sprites, sprite libraries, background images,
  126.    processor-speed adjustment,...
  127.  
  128. What ANIVGA does _not_ support:
  129.  - EMS or XMS memory  (too slow)
  130.  - resolutions other than 320x200x256  (compatibility question)
  131.  
  132.  
  133. 4. "HELLO WORLD" - A First Example
  134. ──────────────────────────────────
  135.  
  136. ANIVGA uses a non-standard 320x200x256 graphic mode, different from the BIOS-
  137. mode $13, but there should be no problems with all truly compatible VGA cards.
  138. To see if ANIVGA is compatible with your system and to get a first impression
  139. of its ease of use, compile the following simple program (you can find it on
  140. disk as file "EXAMPLE1.PAS"):
  141.  
  142. (Remember to copy and compile ANIVGA.PAS in your TurboPascal-Unit-directory
  143.  first)
  144.  
  145. PROGRAM Example1;
  146. USES ANIVGA,CRT;
  147. CONST LoadNumber=42; {why not 42? - A "hello" to all Douglas Adam fans!}
  148.       SpriteName='FLOWER.COD'; {Path and name of the sprite to load}
  149.       Sprite1=0;
  150.       Sprite2=5;
  151. VAR ch:CHAR;
  152.     collide:BOOLEAN;
  153.  
  154. BEGIN
  155.  IF loadSprite(SpriteName,LoadNumber)=0
  156.   THEN BEGIN
  157.         CloseRoutines;
  158.         WRITELN('Error: '+GetErrorMessage); halt(1)
  159.        END;
  160.  
  161.  InitGraph;
  162.  
  163.  Color:=66;
  164.  BackgroundLine(0,0,XMAX,0); BackgroundLine(XMAX,0,XMAX,YMAX);
  165.  BackgroundLine(XMAX,YMAX,0,YMAX); BackgroundLine(0,YMAX,0,0);
  166.  BackgroundOutTextXY(100,70,'Hello world!');
  167.  
  168.  SpriteN[Sprite1]:=LoadNumber;
  169.  SpriteX[Sprite1]:=0; SpriteY[Sprite1]:=0;
  170.  
  171.  SpriteN[Sprite2]:=LoadNumber;
  172.  SpriteX[Sprite2]:=XMAX SHR 1; SpriteY[Sprite2]:=YMAX SHR 1;
  173.  
  174.  WHILE KeyPressed DO ch:=ReadKey;
  175.  Animate;
  176.  REPEAT
  177.   collide:=Hitdetect(Sprite1,Sprite2);
  178.   if collide THEN BEGIN Sound(1000); Delay(5); NoSound END;
  179.   if KeyPressed
  180.    THEN BEGIN
  181.          WHILE KeyPressed do ch:=UpCase(ReadKey);
  182.          CASE ch OF
  183.           'I':DEC(SpriteY[0]);
  184.           'J':DEC(SpriteX[0]);
  185.           'K':INC(SpriteX[0]);
  186.           'M':INC(SpriteY[0]);
  187.           'A':DEC(StartVirtualX,10);
  188.           'S':DEC(StartVirtualX,10);
  189.          END;
  190.          IF POS(ch,'IJKMAS')>0 THEN Animate;
  191.         END;
  192.  
  193.  UNTIL ch='Q';
  194.  
  195.  CloseRoutines;
  196. END.
  197.  
  198. (Don't worry if you do not understand the whole program at once - it should
  199.  only give you a first impression of ANIVGA's capabilities)
  200. If you run this program (make sure that the sprite file FLOWER.COD can be found
  201. by the program!) you should see a graphic consisting of two flowers, a rec-
  202. tangle showing the screen boundaries and the words "Hello world" near the
  203. middle of the screen.
  204. You can move the top left flower by using the keys "I","J","K","M".
  205. If you hit the other flower with the first one, the program will beep.
  206. Try out what happens if you move across the two words in the middle: obviously,
  207. the two leafs of the sprite behave somehow different: the black parts of left
  208. leaf are "transparent" in that the writing shines through it, while the black
  209. parts of the right leaf are "covering black".
  210. But the writing (which is written in the background image) won't be destroyed.
  211. As soon as you leave them, the words will be alright again.
  212. Move the sprite to the very left screen boundary - and move it even more to
  213. the left: you'll get the impression that it moves off the screen until it is
  214. totally offscreen.
  215. Hmmmm - how do we get it back? Sure, "K" will do, but press "A" instead: this
  216. will "pan" the whole screen 10 pixels to the left (think of that as if you
  217. could control an imaginary camera to slide to the left), "S" pans into the
  218. other direction (note the restriction of the program to non-scrolling back-
  219. ground at this point: the big rectangle and the words "Hello world" won't
  220. move because they are part of the so-called "static" background image).
  221. Now -using the "I","J","K" and "M" keys- bring back your sprite to the 2nd one
  222. and let them collide. Press "A" a few times to scroll them both offscreen.
  223. As you'll notice, the program will not stop beeping: it indicates that the two
  224. sprites collide, even if they are not visible to you!
  225. Okay, that should be enough for a first impression, so hit "Q" to quit the
  226. program, if you've finished wondering... :-)
  227.  
  228. Run EXAMPLE2.PAS for a demonstration of "scrolling" background; the program is
  229. much the same as EXAMPLE1, but uses four different "tiles" to build the back-
  230. ground image. As before, you can use "I,J,K,M" to move your sprite along, but
  231. this time, you may scroll the whole scene (incl. the background!) with the
  232. "E,S,D,X" keys, too ("Q" quits, as before).
  233.  
  234. EXAMPLE3.PAS shows (an extremely) simple use of the "Display_SHADOW" mode to
  235. display a graphical object: a sprite is used for its own shadow zone, simply by
  236. redrawing it with a little horizontal and vertical offset.
  237. Although this is a nice trick with many sprites (you don't have to design extra
  238. shadow sprites this way), it doesn't always work: note that there is one area
  239. in the flower which differs from what we would expect as shadow: this is
  240. because ANIVGA assumes that everything between the left- and rightmost point of
  241. a sprite belongs to the sprite's interior and will be drawn accordingly.
  242. (To circumvent this, one would have to draw one (or even several) especially
  243.  designed "shadow zone" sprites for the flower, but we'll come to these aspects
  244.  later)
  245. Pressing "P" draws 1000 randomly distributed points so you can better see the
  246. shadowing effect for single points.
  247. Finally, "C" copies part of the screen into memory (with GetImage() ) and
  248. pastes it somewhere else (with PutImage() ) while clipping off at the screen
  249. boundaries.
  250.  
  251. EXAMPLE4.PAS is an example how to use "sprite cycles": there are six images in
  252. the sprite (library) file HANTEL.LIB which become "glued" together to form one
  253. sprite cycle.
  254. App. one hundred copies of this sprite are then animated on the screen with
  255. maximum animation speed and again, you can scroll the whole screen area with
  256. the keys "E","S","D","X". When you do, you will note that as more and more of
  257. the sprites gets scrolled offscreen, the remaining sprites will rotate faster.
  258. Pressing the space bar will toggle between fastest animation (no time limit)
  259. and an animation rate of 200ms per frame.
  260. You can play around with this value to find out an "optimal" time for your PC
  261. and this program:
  262.  
  263.  very small: program will show the same symptoms as mentioned above (being
  264.              faster for every sprite offscreen)
  265.      .
  266.      .
  267.      .
  268.  very big  : program will slow down even when all sprites are onscreen
  269.  
  270. Somewhere between lies a value where the animation doesn't get slowed down when
  271. all sprites are onscreen (=max. work for ANIVGA), but stays at the same speed
  272. for all other cases (=less work for ANIVGA).
  273.  
  274.  
  275. 5. How ANIVGA works
  276. ───────────────────
  277.  
  278. (It would be _impossible_ trying to cope every detail of ANIVGA, but I'm sure
  279.  you will get the basic ideas of ANIVGA very soon.)
  280.  
  281. As already mentioned, the program uses a "tweaked" VGA-graphic mode: the VGA
  282. is programmed in a way to give 4 graphic pages at a resolution of 320x200
  283. pixels in 256 colors ("they said it couldn't be done, but here it is!..."),
  284. numbered 0..3.
  285. Page 0 and 1 are used for the display, page 2 holds the "normal" background
  286. image and page 3 can contain so-called "tiles" which can be used to build a
  287. huge background image in "scrolling" background mode.
  288. The basic idea of the "page flipping" scheme used is that: do everything (era-
  289. sing the old graphic page, draw sprites/lines/pixels/text) on a graphic page
  290. invisible to the user while showing him a completed page on the screen.
  291. Then, if finished, "flip" the page, thus making the new, completed page visible
  292. and the old page to the invisible one. Now start creating the next image on
  293. this new invisible page - and so on.
  294. "Erasing" the old image means: overdraw it completely with the background image
  295. stored in page 2 (or 3), so one could write in pseudo code:
  296.  
  297.    ...
  298.   REPEAT
  299.    show page 0 to user;
  300.    fill (invisible) page 1 with contents of page 2;
  301.    draw new sprites and all other stuff on page 1;
  302.    show page 1 to user;
  303.    fill (invisible) page 0 with contents of page 2;
  304.    draw new sprites and all other stuff on page 0;
  305.   UNTIL DOOMSDAY
  306.    ...
  307.  
  308. You as the programmer doesn't have to think much about this mechanism, the
  309. routines keep track of the page flipping automatically: the global variable
  310. "PAGE" always holds the number of the page which is invisible (and thus:
  311. the page to be drawn on). Therefore, we say that PAGE holds the "actual page"
  312. number and 1-PAGE is the page visible to the user.
  313. Most of the procedures and functions of the animation package adjust themselves
  314. to the appropriate page; there are only a few situations where you have to be
  315. aware of this mechanism, mostly when drawing pixels or to create special
  316. effects.
  317.  
  318. The whole package is "table driven". That means, the interface to the user
  319. consists of some tables in which you specify your sprites to be drawn:
  320. You store into this tables which sprites to draw ("SpriteN[]") and their
  321. coordinates (in "SpriteX[]" and "SpriteY[]").
  322. After this, a call of the main routine "Animate()" gives back control to the
  323. animation routines, which update the graphic screen accordingly:
  324.  
  325. ...
  326. REPEAT
  327.  update SpriteN[]-table:
  328.    deactivate sprite i by storing a "0" into SpriteN[i]   or
  329.    activate a sprite k by storing k in an unused SpriteN[]-entry   or
  330.    let all the other SpriteN[]-entries as they were last cycle
  331.  FOR ALL SpriteN[i]<>0 DO
  332.    IF SpriteN[i] should change its coordinates
  333.      THEN update (SpriteX[i],SpriteY[i]) accordingly
  334.  call Animate() to draw image and display it
  335. UNTIL end-of-computer-life
  336. ...
  337.  
  338. You should notice that there are two kinds of "sprite numbers" which should
  339. not be mixed up: one is a spriteLOAD number and represents a handle to the
  340. (physical) sprite data, while the other (normally termed "sprite number") is
  341. a logical number to address this sprite data.
  342. In the pseudo code given above, "k" is the spriteLOAD number (it is a number
  343. given at load time) and the index "i" in SpriteN[i] is the sprite number.
  344. Note that "k" is a unique value: you can think of it as a NAME of the sprite
  345. data loaded (e.g. you could name the FLOWER.COD - data as "123" when loading
  346. it: there can't be another sprite with the same LOAD-number). On the other
  347. hand, there could be a hundred flowers on the screen: just choose hundred
  348. different sprite-table entries (=sprite numbers), e.g. SpriteN[100]..
  349. SpriteN[199] and store "123" in each of them!
  350. Whenever you are unsure if you (or I) are speaking of a "sprite number" or a
  351. "spriteLOAD number", remember that:
  352.  
  353.  ■ A sprite number can hold values in the range 0..NMAX and is an index of
  354.    the tables SpriteX[], SpriteY[] and SpriteN[].
  355.  ■ A spriteLOAD number can hold values between 0..LoadMax and is assigned
  356.    as a "name" to the sprites' physical loaded data; a "0" as load number is
  357.    reserved for "inactivate sprite"
  358.  
  359.  
  360. The world ANIVGA knows is 32000 pixels wide and high, numbered -16000..+16000
  361. on each axis. Because your graphic screen consists of only 320 by 200 points,
  362. (ranging from 0..XMAX and 0..YMAX in the x- and y-axis, respectively; (0,0) is
  363.  the upper left corner, (XMAX,YMAX) the lower right one) you can only see a
  364. small part of this world, but ANIVGA does not distinguish between the visible
  365. and invisible parts of the world. If, for example, two sprites collide, the
  366. routine "HitDetect()" will find out, even if this collision occurs offscreen.
  367. Thus you can think of your graphic display being a "camera" to the real world:
  368. your actions can take place everythere in this virtual world, but you see only
  369. the part displayed by your camera; if you wish to see another part of your
  370. world, you have to move this imaginary camera to that place.
  371. In ANIVGA, you can do this by changing the values "StartVirtualX" and
  372. "StartVirtualY" which hold the upper left corner of the visual window. As an
  373. example, let (StartVirtualX,StartVirtualY) be (1000,500): then on your screen
  374. you will see the part of the world which ranges from coordinates (1000..1319)
  375. and (500..699) in X- and Y-directions, respectively.
  376.  
  377.  
  378. 6. Tips, tricks and techniques
  379. ──────────────────────────────
  380.  
  381. There would be a lot of things to say and most of them will be mentioned in the
  382. following "Reference Manual". Nevertheless, it seems reasonable to repeat them
  383. in a more concentrated form here, although this happens to make this chapter a
  384. real topsyturvydom...
  385.  
  386. a) The ERROR-concept: if an error occurs in one of ANIVGA's routines, the
  387.    global variable ERROR will be set accordingly. This gives you the freedom
  388.    either to check this variable each time you called a routine - or ignore it
  389.    for improved speed.
  390.    As a rule of thumb, you should always check this variable while your program
  391.    is still in the testing phase - and "comment out" these sections when you
  392.    are through with debugging. (Conditional defines are great for that job!)
  393.    Note that there are some routines that do not set ERROR at all (like Screen,
  394.    GetPixel, PageGetPixel, PagePutPixel), either because in some special cases,
  395.    "nice" tricks can be played with "faulty" parameters or because of severe
  396.    speed improvements! For example, if you are going to read a 5000 pixel area
  397.    from the screen with PageGetPixel(), it would be crazy to check 5000 times
  398.    whether the "page" given to read from is valid or not.
  399.  
  400. b) Pixel-drawing routines: basically spoken, there are three sorts of graphic
  401.    data objects in ANIVGA: sprites, pixels and background images.
  402.    Because of ANIVGA's working scheme, all routines handling pixels (PutPixel,
  403.    PagePutPixel, Line, PutImage,...) must be used in a special form:
  404.    - If you use them to "draw" into the background page, this can only be done
  405.      when using background mode STATIC (because in mode SCROLLING, the back-
  406.      ground is stored in a compressed format one can't access directly).
  407.    - Drawing into the background page in mode STATIC is fine (that's the main
  408.      advantage of this mode compared with mode SCROLLING), and the best time to
  409.      do it is _before_ calling Animate(), because changes to the background
  410.      image will then be visible with the call to this routine.
  411.    - Drawing "on the monitor screen" will be visible exactly for one animation
  412.      cycle, that is: until the next call to Animate(). For this reason, you
  413.      must do this changes _after_ calling Animate() and at the _visible_ page
  414.      1-PAGE (not the _actual_ page PAGE itself).
  415.  
  416.      It is not that difficult as it may sound at first glance; for example:
  417.      ...
  418.      REPEAT
  419.       read_user_inputs; compute_necessary_actions;
  420.        do_all_changes_to_the_background_image;
  421.        do_all_changes_to_the_sprites;
  422.        Animate();
  423.        do_all_changes_to_the_visible_screen; {e.g.: Line(0,0,XMAX,YMAX,1-PAGE)}
  424.      UNTIL user_wants_to_end_application
  425.      ...
  426.  
  427.      This way, after having called Animate(), the changes to the background
  428.      (and your sprites) will be visible (because Animate() has generated an
  429.      appropriate picture) and your changes to this image with the pixel-
  430.      drawing routines will be visible "at once".
  431.      That image will then stay visible until the next call to Animate().
  432.      (Simply spoken, you let Animate() generate and display a picture and then
  433.       do some changes to the picture while it is diplayed)
  434.    - Because of unavoidable memory restrictions, ANIVGA can't store pixels
  435.      drawn offscreen: if ANIVGA sees that points/lines lie outside the visible
  436.      screen, it just does nothing at all; in other words, you can't draw a line
  437.      outside the screen and "scroll it in" five minutes later! (You would have
  438.      to define the line as a sprite instead, because sprites are the only
  439.      objects stored independently).
  440.  
  441. c) Coordinates: Throughout all routines, ANIVGA works with _virtual_ coordi-
  442.    nates (that is, values in the range xε[-16000..+16000], yε[-16000..+16000]),
  443.    but sometimes you will have to address _absolute_ coordinates (in the range
  444.    xε[0..XMAX], yε[0..YMAX]), so you have to transform virtual coordinates into
  445.    absolute coordinates (or vice versa), which is _very_ easy:
  446.  
  447.    virtual coordinates -> absolute coordinates:
  448.       Xabsolute := Xvirtual - StartVirtualX
  449.       Yabsolute := Yvirtual - StartVirtualY
  450.  
  451.    absolute coordinates -> virtual coordinates:
  452.       Xvirtual  := Xabsolute + StartVirtualX
  453.       Yvirtual  := Yabsolute + StartVirtualY
  454.  
  455. d) Background / valid pages: Many routines expect a graphic page number as
  456.    parameter. As mentioned under b), BACKGNDPAGE is valid only when you use
  457.    background mode STATIC. Nevertheless, you can draw to this page even when
  458.    you are using background mode SCROLLING without getting an error
  459.    "Err_InvalidPageNumber" (although you are _strongly_ discouraged to do so)!
  460.    That's because you can play some tricks on ANIVGA this way, provided that
  461.    you do know _exactly_ what you (and ANIVGA) are doing, but this "feature"
  462.    will probably be cut off in future versions of this program.
  463.    (Note that this doesn't mean that you can't switch between STATIC and
  464.     SCROLLING backgrounds during runtime! - It only says that you can't use
  465.     the two background pages _in parallel_ (=at the same time)!)
  466.  
  467. e) Display objects at the same abolute screen position:
  468.    Let us assume you want to display a score at the upper right corner of the
  469.    screen; that's not hard when using STATIC background: just define your
  470.    score as a sprite and choose an appropriate coordinate pair.
  471.    In SCROLLING mode, your score would scroll away, too, so you must tie it to
  472.    absolute screen coordinates, as said in c), but there is a simple rule which
  473.    can be derived from the equation
  474.  
  475.       absolute_coordinate := virtual_coordinate - StartVirtual_value
  476.  
  477.    To ensure that the absolute (=screen) coordinate stays the same, you have to
  478.    balance out changes done to the StartVirtual-variables like this: whenever
  479.    you increase/decrease StartVirtual? by some amount delta, increase/decrease
  480.    your score-coordinates by the same amount delta!
  481.    (This results in: new_coord := virtual_coord±delta - (StartVirtual±delta)
  482.     = virtual_coord - StartVirtual = old_coord    as wanted)
  483.  
  484. f) Displaying scores: another way to display a score without defining it as a
  485.    sprite would be to simply draw it to the screen with the pixeldrawing rou-
  486.    tines or OutTextXY():
  487.     ■ draw it to the visible page (1-PAGE) each time after having called
  488.       ANIMATE()
  489.     ■ draw it to the background page BACKGNDPAGE
  490.    The last method is applicable only in background mode STATIC and you have
  491.    to restore the background image in the used area manually, but has the ad-
  492.    vantage that you must redraw your score only when it really changed (instead
  493.    of every animation cycle as with the first method). One way to accomplish
  494.    that would be to use the GetImage() and PutImage() routines:
  495.    ...
  496.    build background image;
  497.    use GetImage() to get a copy of the background area which will be overdrawn
  498.    by the score;
  499.    ...
  500.    main_loop:
  501.     IF new score has to be displayed
  502.       THEN BEGIN
  503.             use PutImage() to restore old background area underneath the score;
  504.             use OutTextXY() to write new score into the background image
  505.            END
  506.    ...
  507.  
  508. g) Speed: It is hard to predict the speed of animations, because that is merely
  509.    determined by the speed of your VGA card, not your computer's CPU clock
  510.    rate! E.g., a program runs faster on my old AT (8MHz) than on a fast (25
  511.    MHz) 80386 machine - only because of a better VGA card installed in the AT!
  512.    Stated otherwise, if you use a computer with "enough" CPU-power, you won't
  513.    have to think much about "should I use STATIC background instead of SCROL-
  514.    LING for improved speed?", because it won't matter anyway!
  515.    The break even point, where the VGA-card's bottle neck becomes the limiting
  516.    factor depends largely on your application (and your VGA-card, of course),
  517.    but as a rule of thumb, clock speeds faster than 12MHz won't improve your
  518.    program speeds *linearly* any further:
  519.  
  520.         animation  ^            ______
  521.         speed      │     ___----
  522.                    │    /
  523.                    │  /
  524.                    │/
  525.                    ┼─────┬───────────>  clock rate
  526.                          break-
  527.                          even point
  528.  
  529.    Note that your programs will still profit from faster CPU's, but that is due
  530.    to faster computation of all routines not limited by accessing the video
  531.    RAM; even on the fastest clones, the IBM-bus-clock-rate is not faster than
  532.    10MHz  -- and this limits accessing the VGA card: sad, but true...
  533.  
  534. g) DMA access: Quite a long time, I tried to speed up animation rates by using
  535.    the DMA-chip in parallel to the CPU: while the CPU is running your program,
  536.    the DMA should move around memory.
  537.    Unfortunately, I had to find out that most computers don't like DMA memory-
  538.    to-memory transfers at all and those who do don't work when addresses used
  539.    reference the video RAM area (I can't explain why this is the case).
  540.    If someone out there has successfully worked with the DMA chip this way, I
  541.    would be glad to know!
  542.  
  543.  
  544. 7. Credits
  545. ──────────
  546.  
  547. Honour to whom honour is due! Although most of the routines are mine, two of
  548. the utility programs (also written in TP6.0) use stuff from other Freeware
  549. authors:
  550.  
  551. - The GRAB-utility uses Ken Pottebaum's TSR-unit TSRUNIT.ZIP       and
  552. - The MAKES-designer uses John Bridges' BGI-driver SVGA256.BGI (for the VGA's
  553.   320x200x256 mode $13) from his SuperVGA-driver package SVGABGI3.ZIP
  554.  
  555. (Both programs are available at the SIMTEL20-servers)
  556.  
  557. Thanks to them for supporting the Freeware-concept, their spirit made it
  558. possible to distribute this program as Freeware, too!
  559.  
  560.  
  561. 8. ANIVGA Reference Manual
  562. ──────────────────────────
  563.  
  564. This reference manual lists all routines, variables, constants and a lot of in-
  565. formational stuff concerning ANIVGA in alphabetic order.
  566. Don't get frightened about the amount of informations given; in normal appli-
  567. cations you will need only a few of them!
  568.  
  569.  
  570. ABSOLUTE COORDINATES - information
  571. ──────────────────────────────────
  572.  
  573. See       : coordinates
  574.  
  575.  
  576. Animate - procedure
  577. ───────────────────
  578.  
  579. Function   : Performs a complete animation cycle
  580.  
  581. Declaration: {$F+} PROCEDURE Animate {$F-}
  582.  
  583. Description: A call to Animate() clears the invisible graphic page by copying
  584.              the contents of the background image into the actual drawing
  585.              page (specified by variable PAGE).
  586.              Then all active sprites (SpriteN[i]<>0) in the visible window
  587.              (determined by StartVirtualX and StartVirtualY) are drawn in the
  588.              style and at the coordinates given by the user.
  589.              After that, the routine waits for a vertical retrace to reprogram
  590.              the VGA adapter to flip the display pages, making the completed
  591.              image visible and changes PAGE to point to the new, invisible
  592.              graphic page.
  593.              Finally, the procedure looks how much time passed since the last
  594.              animation cycle and if this time is less than that set by
  595.              SetCycleTime(), the program waits accordingly.
  596.  
  597. Note       : This procedure is the kernel routine which has to be called every-
  598.              time when you have set all data for a new animation frame.
  599.  
  600. See also   : PAGE, SetCycleTime, StartVirtualX, StartVirtualY
  601.  
  602.  
  603. BackGndPage - constant
  604. ──────────────────────
  605.  
  606. Function   : Holds the page number of the backround page
  607.  
  608. Declaration: CONST BACKGNDPAGE=2;
  609.  
  610. Description: When using background mode STATIC, BackGndPage specifies the page
  611.              number of the background image for the animations to be used.
  612.  
  613. Note (!)   : Use of this constant only makes sense when using background mode
  614.              STATIC!
  615.  
  616. See also   : ScrollPage, Background
  617.  
  618.  
  619. Background - information
  620. ────────────────────────
  621.  
  622. The term "background" specifies a graphic image in front of which all anima-
  623. tions take place.
  624. There are two sorts of background in ANIVGA: SCROLLING background and STATIC
  625. background, which you choose with SetBackgroundMode().
  626.  
  627. As its name states, a STATIC background cannot be scrolled: it consists of a
  628. 320x200 pixels picture.
  629. This background picture is stored in the graphic page numbered BACKGNDPAGE.
  630. At the very start of every animation cycle, the routine Animate copies that
  631. picture into the actual drawing page, thus erasing old stuff on that page and
  632. building the basis for the new image.
  633. As a normal bitmap picture, it is 320x200=64000 bytes in size. If you use the
  634. GRAB-Utility or the WritePage()-Routine to save an image, a three byte header
  635. is put ahead of the information, thus extending the size to 64003 bytes.
  636.  
  637. The second background sort is called SCROLLING: like ANIVGA's virtual coor-
  638. dinates, you can define a huge background image and scroll over it.
  639. Unfortunately, it is impossible to hold a complete background picture in
  640. memory: you would need 32000*32000=1024000000 bytes RAM (!) to do that.
  641. Instead, ANIVGA uses a "tiling" mechanism: tiles are small pictures (16x16
  642. pixels) which can be combined freely to build the background image.
  643. You can use up to 256 different tiles and "pin" them on an background area of
  644. up to MaxTiles (=10000) tiles; everything outside of this background area will
  645. be assigned to tile no. 0 automatically.
  646. For example, let us assume that you use only scrolling in the y-coordinate
  647. axis, 16 screens in total: thus, your x-coordinates reach from 0 to 319 and
  648. your y-coordinates from 0..(16*200-1)=5119, which gives an area of 320*5120
  649. =1638400 pixels.
  650. This is equivalent to (320/16)*(5120/16)=20*320=6400 tiles (remember: each
  651. tile consists of 16x16 pixels!).
  652. So you would define the scroll range for the background area needed with
  653. SetBackgroundScrollRange(0,0,319,5119) and start "painting" your background:
  654. You could design up to 256 different tiles and use them to assemble your
  655. background image (=those 6400 tiles).
  656. Most often, only a few are needed, because the background image isn't that
  657. dramatically different all over the place. For simplicity, let's assume that
  658. you need only 20 different tiles, numbered 0..19 respectively in the following
  659. order to build your background image:
  660.  
  661.   (0,0)                                                         (319,0)
  662.     ┌────────┬────────┬────────┐         ┌────────┬────────┬────────┐
  663.     │        │        │        │         │        │        │        │
  664.     │   0    │   1    │   2    │   ...   │   13   │   14   │   15   │
  665.     │        │        │        │         │        │        │        │
  666.     ├────────┼────────┼────────┤         ├────────┼────────┼────────┤
  667.         .        .        .                  .        .        .
  668.         .        .        .                  .        .        .
  669.         .        .        .                  .        .        .
  670.     ├────────┼────────┼────────┤         ├────────┼────────┼────────┤
  671.     │        │        │        │         │        │        │        │
  672.     │   0    │   1    │   2    │   ...   │   13   │   14   │   15   │
  673.     │        │        │        │         │        │        │        │
  674.     └────────┴────────┴────────┘         └────────┴────────┴────────┘
  675.   (0,5119)                                                      (319,5119)
  676.  
  677. Now all you have to do is to tell ANIVGA that layout with the PutTile command:
  678.  
  679.  {assuming SetBackgroundScrollRange(0,0,319,5119) has been set}
  680.  number:=0;
  681.  y:=0; {better: y:=BackY1}
  682.  REPEAT  (things would become easier if Pascal would know a STEP-command...)
  683.   x:=0; {better: x:=BackX1}
  684.   REPEAT
  685.    PutTile(x,y,number);
  686.    number:=(number+1) MOD 16;
  687.    inc(x,16);
  688.   UNTIL x>319; {better: x>BackX2}
  689.   inc(y,16);
  690.  UNTIL y>5119; {better: y>BackY2}
  691.  
  692. That's it! (It is better to use the (global defined) "Back..."-variables, set
  693. by the former SetBackgroundScrollRange()-call, because ANIVGA has to adjust
  694. values on multiples of 16, see SetBackgroundScrollRange()/Back?? for more
  695. details).
  696.  
  697. So then, why should one use STATIC backgrounds after all when there is such a
  698. powerful instrument like SCROLLING backgrounds?
  699. There are two simple answers: speed and simplicity! - First, SCROLLING back-
  700. grounds take a lot of work to compute, which slows down animations (unless you
  701. have a fast machine, because then the VGA's memory access time becomes the
  702. limiting factor). Second, it is easy to do some "tricks" on static backgrounds:
  703. draw a line in the static background page and >zap!< starting with the next
  704. animation cycle, it will be visible for all times. Stated otherwise, when using
  705. scrolling background, you cannot use drawings to the background image, because
  706. it simply doesn't exist explicitly, you are restricted solely to "tiles" and
  707. "sprites"! (On the other hand, you can play nice tricks on scrolling background
  708. by changing single tiles...)
  709. So consider carefully what mode you are going to use for your application!
  710.  
  711. See also   : BACKGNDPAGE, BACKGNDADR, WritePage, LoadPage, WriteBackgroundPage,
  712.              LoadBackgroundPage, SetBackgroundMode, LoadTile, Tile
  713.  
  714.  
  715. BackgroundGetPixel - function
  716. ─────────────────────────────
  717.  
  718. Function   : Reads a background pixel's color
  719.  
  720. Declaration: {$F+} FUNCTION BackgroundGetPixel(x,y:INTEGER):BYTE; {$F-}
  721.  
  722. Description: This routine will return the color value of the specified point
  723.              with virtual coordinates (x,y) in the background image.
  724.              If the corresponding absolute coordinates lie outside the screen,
  725.              zero (= black) will be returned.
  726.  
  727. Note       : Use of this routine works only when using background mode STATIC!
  728.              It might look strange to use virtual coordinates then, although
  729.              the background is said to be static (= non-scrollable) and hence
  730.              restricted to absolute coordinates anyway, but it is often con-
  731.              venient to use an uniform notation and it is easy to convert co-
  732.              ordinates accordingly (see "coordinates" for more about that).
  733.  
  734. See also   : coordinates, GetPixel, PageGetPixel
  735.  
  736.  
  737. BackgroundLine - procedure
  738. ──────────────────────────
  739.  
  740. Function   : Draws a line on the background page
  741.  
  742. Declaration: {$F+} PROCEDURE BackgroundLine(x1,y1,x2,y2:INTEGER); {$F-}
  743.  
  744. Description: To draw a line on the background page (thus alterating the back-
  745.              ground), you can use this procedure. Like the similiar Line()-
  746.              routine, it uses virtual coordinates, too.
  747.              If necessary, the line will be clipped down to its visible part
  748.              (using a special Sutherland-Cohen algorithm).
  749.  
  750. Note       : Use of this routine only makes sense when using background mode
  751.              STATIC!
  752.  
  753. See also   : Line, coordinates
  754.  
  755.  
  756. BackGroundMode - variable
  757. ─────────────────────────
  758.  
  759. Function   : Holds the actual choosen background mode
  760.  
  761. Declaration: VAR BackgroundMode:BYTE;
  762.  
  763. Description: Using SetBackgroundMode(), you can select one of the possible
  764.              background modes STATIC or SCROLLING. BackGroundMode stores this
  765.              value.
  766.  
  767. Note (!)   : Only read this value, never change it directly!
  768.  
  769. See also   : Background, SetBackgroundMode
  770.     
  771.  
  772. BackgroundOutTextXY - procedure
  773. ───────────────────────────────
  774.  
  775. Function   : Writes a textstring to the background page BACKGNDPAGE
  776.  
  777. Declaration: {$F+} PROCEDURE BackgroundOutTextXY(x,y:INTEGER; s:STRING); {$F-}
  778.  
  779. Description: This routine is exactly the same like OutTextXY() (see there), but
  780.              it writes the string into the background page (so it will be visi-
  781.              ble permanently).
  782.  
  783. Note       : Use of the routine only makes sense if STATIC is used as
  784.              background mode.
  785.  
  786. See also   : GraphtextColor, GraphtextOrientation, GraphtextBackground,
  787.              OutTextXY, background
  788.  
  789.  
  790. BackgroundPutPixel - procedure
  791. ──────────────────────────────
  792.  
  793. Function   : Plots a point into the background page
  794.  
  795. Declaration: {$F+} PROCEDURE BackgroundPutPixel(x,y:INTEGER; color:BYTE); {$F-}
  796.  
  797. Description: (x,y) specify the virtual coordinates of the point to be drawn in
  798.              color "color". If this point lies onscreen (i.e.: its _absolute_
  799.              coordinates are between (0,0)..(319,199)), it will be drawn on the
  800.              background page BACKGNDPAGE (and become visible starting with the
  801.              next animation cycle).
  802.  
  803. Note (!)   : - Use of this routine makes sense only when using background mode
  804.                STATIC!
  805.              - This routine works with virtual coordinates! - Although this
  806.                seems silly at first glance (because in STATIC mode, background
  807.                coordinates are always restricted to (0,0)..(319,199)), it
  808.                appears to be handy in many situations. If you actually want to
  809.                address points absolute coordinates (a,b), you can call this
  810.                routine with coordinates (a+StartVirtualX,b+StartVirtualY)
  811.                instead.
  812.              - Because of ANIVGA's working scheme, you probably want to call
  813.                this routine _before_ calling Animate(), so that changes of the
  814.                point will be visible as soon as possible.
  815.  
  816. See also   : PutPixel, PagePutPixel, background, coordinates, How ANIVGA works
  817.  
  818.  
  819. BACKX1, BACKX2, BACKY1, BACKY2 - variables
  820. ──────────────────────────────────────────
  821.  
  822. Function   : Hold the background image boundaries in background mode SCROLLING
  823.  
  824. Declaration: BackX1,BackY1,BackX2,BackY2:INTEGER;
  825.  
  826. Description: When background mode SCROLLING is to be used, you have to define
  827.              a scrolling area (with SetBackgroundScrollRange()). Due to inter-
  828.              nal management restrictions of ANIVGA, the boundaries of this area
  829.              must fall on coordinates which are multiples of 16 ("on a grid
  830.              with mesh 16").
  831.              If the values you supply don't fulfill this restriction, ANIVGA
  832.              adjusts them automatically to do so and stores them to these
  833.              variables for further use.
  834.  
  835. Note       : The only reason these variables are visible to you are that it
  836.              could be necessary for you to notice adjustments ANIVGA did;
  837.              so: only read this values, never change them directly!
  838.              (Look at "background" for an example).
  839.  
  840. See also   : background
  841.  
  842.  
  843. CloseRoutines - procedure
  844. ─────────────────────────
  845.  
  846. Function   : Terminates ANIVGA
  847.  
  848. Declaration: {$F+} PROCEDURE CloseRoutines; {$F-}
  849.  
  850. Description: Calling this routine switches back from ANIVGA's special graphic
  851.              mode into the graphic or text mode previously set.
  852.  
  853. Note       : This should always be the last call to a routine of ANIVGA in your
  854.              programs.
  855.  
  856. See also   : InitGraph
  857.  
  858.  
  859. COLLISION-DETECTION, CONCAVE, CONVEX - information
  860. ──────────────────────────────────────────────────
  861.  
  862. A graphical figure can be classified by its outline into one of two groups,
  863. called "concave" or "convex" figures.
  864. To motivate this mathematical notion >eh, don't get frustrated...<, regard
  865. your sprite only given by its "outmost" points, which connected together shape
  866. the figures boundaries.
  867. The figure is called "convex" :<=> every pair of arbitrarily choosen points
  868. on this boundary build a line which is totally inside (or at least on the
  869. boundary of) the figure:
  870.   ┌──────┐ This rectangle is "convex", because whenever you choose two points
  871.   │      │ on its boundaries and connect them, the resulting line lies com-
  872.   └──────┘ pletely inside (or on the boundary) of the rectangle itself.
  873.  
  874.   ┌──────┐ On the other hand, this figure would be "concave", because if you
  875.   └─┐  ┌─┘ choose the top-right and bottom-right corner (say) and connect them,
  876.   ┌─┘  └─┐ then the middle part of the resulting vertical line lies outside the
  877.   └──────┘ figure.
  878.  
  879. That is (in a very lax form) the _mathematical_ definition of these terms, but
  880. ANIVGA completely deals with either horizontal or vertical lines, so that an
  881. extension of these terms can be made:
  882.  
  883. A sprite is called "horizontal concave" ("vertical concave"), if a horizontal
  884. (vertical) line connecting two points of the sprite's boundary can be found
  885. so that parts of this line lies outside the sprite; if the sprite is not hori-
  886. zontal (vertical concave), it is "horizontal convex" ("vertical convex").
  887.  
  888. In that sense, the second of the figures above is "vertical concave", but
  889. "horizontal convex"!
  890. (Notice that figures which are concave in the pure _mathematical_ sense are
  891.  sometimes treated as convex by this definition, as this cross:)
  892.     ┌─┐     (If you use either a horizontal or vertical "scan line" sweeping
  893.   ┌─┘ └─┐    throughout the cross, there will be never more than one part of
  894.   └─┐ ┌─┘    the "scan line" which belongs to the figure; you can use this
  895.     └─┘      principle as a second definition for horizontal/vertical convex)
  896.  
  897. This terminology comes in handy when describing some mechanisms of ANIVGA: a
  898. sprite is drawn LINEwise. For this, every point between the leftmost and right-
  899. most point of a sprite's line is considered to be an _inner_ point of the
  900. sprite, thus ANIVGA assumes a horizontal convexity! If your sprite isn't, like
  901. this one...
  902.   ┌─────┐  ...and the points between the two "legs" of this sprite shall still
  903.   │ ┌─┐ │  be treated as "transparent" (assuming they have been defined with
  904.   │ │ │ │  color "black" (=0)), you must use display mode "Display_NORMAL",
  905.   │ │ │ │  because the "Display_FAST" mode would treat them as belonging to the
  906.   └─┘ └─┘  sprite itself and draw them as "covering" black.
  907.  
  908. (To state it otherwise: whenever your sprite is (at least) horizontal convex
  909.  and you don't need the feature of transparent parts inside the sprite, you
  910.  can use the "Display_FAST" mode without any loss of accuracy in the sprite
  911.  display)
  912.  
  913. Tip: the spritemaker program MAKES allows to display a sprite's horizontal
  914. boundaries, which makes it easier for the beginner to decide about that
  915. figure's convexity. But whenever you are unsure, you still can use mode
  916. "Display_NORMAL" for drawing it.
  917.  
  918. ---
  919.  
  920. Things get a bit more tough when deciding if two sprites collide or not (which
  921. is an important task): in difference to many sprite toolkits, ANIVGA doesn't
  922. use a "mask" approach, which makes sprites big and collision detection slow.
  923. Instead, ANIVGA uses a sprite's outline to decide whether two sprites collide.
  924. For that, it computes for every line (column) of the overlap region of the
  925. sprites' surrounding rectangles, whether the sprites overlap horizontally
  926. (vertically) and says "collision!" only if there are intersections in both
  927. directions. In pseudo code:
  928.  
  929. IF smallest_box_around(sprite1) doesn't intersect smallest_box_around(sprite2)
  930.  THEN no_collision
  931.  ELSE BEGIN
  932.        compute the lines and columns for which the 2 sprite rectangles overlap
  933.        FOR every such line compare -with the help of the sprite boundaries- if
  934.         the corresponding lines overlap
  935.        FOR every such column do the same check
  936.        ONLY_IF there is an intersection in at least one line AND one column
  937.         THEN collision!
  938.         ELSE no_collision
  939.       END
  940.  
  941. If you think a byte (=8 bits...) about this algorithm, you'll see that it can
  942. lead to misdetection, in that the algorithm says "collision!", although there
  943. is none (but it still guarantees that if there _is_ a collision, the alg. will
  944. detect it) as in the following example:
  945.           ┌─────┐
  946.           └───┐ │
  947.    ┌────────┐ │ │
  948.    │ ┌────┐ │ │ │
  949.    │ │ ┌─┐│ │ │ │  <─ In this line there is a "horizontal collision" (that is,
  950.    └─┘ │ │└─┘ │ │     the two sprites overlap in their horizontal dimension)
  951.        │ └────┘ │  
  952.        └────────┘  ┌─ In this column there is a "vertical collision"
  953.            ^───────┘
  954.  
  955. To state things without a proof here, such an (unavoidable) misdetection is
  956. only possible, if at least one of the two sprites is neither horizontal nor
  957. vertical convex!!!
  958.  
  959. Even then, it takes special constellations (as the one above) to produce such
  960. an error, so that in praxis, it is very unlikely for such an error to occur.
  961.  
  962.  
  963. Color - variable
  964. ────────────────
  965.  
  966. Function   : Determines the actual drawing color
  967.  
  968. Declaration: VAR Color:BYTE;
  969.  
  970. Description: Various drawing routines use this global variable to determine
  971.              which color should be used.
  972.  
  973. Note       : ANIVGA uses the standard color table of the 256-color mode $13.
  974.  
  975. See also   : -
  976.  
  977.  
  978. ColorTable - type
  979. ─────────────────
  980.  
  981. Function   : Supply a data type for self-defined "Shadow Tables"
  982.  
  983. Declaration: TYPE ColorTable=ARRAY[0..255] OF BYTE;
  984.  
  985. Description: If you want to use a different color look-up-table for your
  986.              sprites in display mode Display_SHADOW than can be achieved with
  987.              SetShadowTab(), you must build a table like this.
  988.              Each entry gives the color which should be used to replace the
  989.              original color with that index, i.e.: if c is of type ColorTable
  990.              and c[5]=9, this means that every point of your sprite which is to
  991.              be drawn over a pixel with color 5 should replace that pixel with
  992.              color 9.
  993.              You can find an example how to activate such a "home-brew" table
  994.              at "ShadowTab".
  995.  
  996. Note       : -
  997.  
  998. See also   : ShadowTab, SetShadowTab, Display modes
  999.  
  1000.  
  1001. COORDINATES - information
  1002. ─────────────────────────
  1003.  
  1004. ANIVGA has to deal with two kinds of coordinates: "virtual" and "absolute" ones.
  1005. An absolute coordinate lies in the range 0..319, 0..199 for the x and y values,
  1006. respectively. It names a unique point on your graphic screen.
  1007. However, ANIVGA doesn't restrict animations to take place on the visible
  1008. graphic screen: its routines deal with coordinates in the range -16000..+16000
  1009. in each direction, called "virtual coordinates".
  1010. The picture you view while ANIVGA's routines are running is a window of that
  1011. virtual screen, 320 points wide and 200 points high.
  1012. Naturally, the graphic hardware only knows absolute coordinates and thus,
  1013. ANIVGA has to transform virtual in absolute coordinates. It does this with the
  1014. help of the two variables StartVirtualX and StartVirtualY which together speci-
  1015. fy the starting point of the upper left corner of your actual screen window;
  1016. e.g. if (StartVirtualX,StartVirtualY) was (1000,2000) then you would look at
  1017. the part of ANIVGA's world which consists of the 320x200 region with the coor-
  1018. dinates xε(1000..1319) and yε(2000..2199).
  1019. Note that there is one severe restriction, though: because it is absolutely
  1020. impossible to hold a complete "virtual" screen bitmap for ANIVGA's world in
  1021. memory (it would need app. 1GB RAM!), all drawing commands only take place on
  1022. the visible screen.
  1023. This means that you can't draw lines, points or any other objects which are
  1024. _not_ sprites outside the visible window that become visible, when you scroll
  1025. your window over to that part of the virtual screen. For example, if you draw
  1026. a point somewhere outside your visible window (say at (-10000,1234) while your
  1027. visible window starts at (500,900)) and pan to that region afterwards (by set-
  1028. ting (StartVirtualX,StartVirtualY)=(-10100,1200) or something like that), you
  1029. won't see that point: it is stored nowhere.
  1030. (The only way to circumvent this is to define the point as a sprite and set its
  1031.  coordinates (SpriteX[],SpriteY[]) to (-10000,1234), because sprites are the
  1032.  only objects which the system stores!).
  1033.  
  1034. More general:
  1035. Because there is _no_ complete virtual screen, all information drawn outside
  1036. the coordinate range visible at the moment will be lost and all information
  1037. read in from these "offscreen" pixel positions will be zero (= black).
  1038. For that reason it may seem strange for some routines that were restricted in
  1039. their use to the "real" (= absolute coordinate) screen region to use virtual
  1040. coordinates inspite (e.g.: GetImage, BackGroundGetPixel,...), but this was done
  1041. intentionally, because it leaves room for further improvements: if it should be
  1042. possible some day to store a complete virtual screen image, there will be no
  1043. changes necessary in ANIVGA's syntax.
  1044. Meanwhile, it is simple to transform absolute and virtual coordinates into each
  1045. other whenever necessary, using the following equivalence:
  1046.  
  1047.   virtual X-coordinates - StartVirtualX = absolute X-coordinates
  1048.   virtual Y-coordinates - StartVirtualY = absolute Y-coordinates
  1049.  
  1050. As a result: virtual coordinates lie in the range -16000..+16000, the start of
  1051. the visible part is defined in StartVirtualX and StartVirtualY and only sprites
  1052. can be "scrolled in" into the visible screen, while all other objects are
  1053. "lost".
  1054.  
  1055.  
  1056. Display modes - information
  1057. ───────────────────────────
  1058.  
  1059. ANIVGA is able to display a sprite in several "modes". This describes how the
  1060. sprite's data should be handled when drawing the sprite to the screen. Up to
  1061. now, there are three modes:
  1062.  - Display_NORMAL  
  1063.  - Display_FAST
  1064.  - Display_SHADOW
  1065. This mode is linked to a sprite's physical data by creation of the sprite with
  1066. the spritemaker program (and defaults to Display_NORMAL), but can be altered
  1067. once the sprite is loaded into memory with the procedure SetModeByte().
  1068.  
  1069. Note that the display mode information is part of the _physical_ sprites (that
  1070. is, the memory image of the bytes loaded at the beginning), not the _logical_
  1071. sprites (the "handles" in the SpriteN-array to this physical data). For that
  1072. reason, a change of the display mode of a sprite with spriteLOAD number 123
  1073. (say) will affect _all_ sprites of type 123 (= all entries in SpriteN[] with
  1074. value 123). This is intended, because the display mode is a piece of informa-
  1075. tion reflecting the sprite's physical structure.
  1076.  
  1077. In mode "Display_NORMAL" you can think of a sprite as a picture with holes at
  1078. the places where its pixels have color 0: when displayed, all the parts of the
  1079. sprite with color<>0 will cover (paint over) the screens original pixels, but
  1080. the pieces with color=0 will act like "window panes": the original contents of
  1081. the screen remain visible there.
  1082. This mode is useful for all kinds of sprites which have such opaque holes in-
  1083. side themselves: cars/planes/houses or other objects with window panes, but
  1084. also all "concave" sprites. Note that black, covering parts must be realized
  1085. with a dark color<>0, for example color 16.
  1086.  
  1087. "Display_FAST" is a bit (but not that dramtically) faster than the last method,
  1088. because it doesn't know of a special color: all sprite data is treated equally
  1089. and stored to the screen at once. For that, all parts of the sprite are
  1090. covering. (But note that a sprite consists only of the points inside and on its
  1091. boundaries: all the points of the smallest box surrounding it -that is the way
  1092. a sprite is stored- doesn't matter).
  1093. You will use this mode whenever you have sprites which meet the following re-
  1094. quirements: they are "convex" and don't have any transparent parts inside them-
  1095. selves.
  1096.  
  1097. "Display_SHADOW" is a tribute to the fact that one often needs some kind of
  1098. shadowing to give the impression of an freefloating object or other pseudo
  1099. 3D-effects. In this mode, the sprite's real colors are insignificant, only its
  1100. boundaries and the actual contents of the screen where the sprite shall be
  1101. drawn are important. The color of every sprite point is determined by the color
  1102. of the appropriate screen point. The color of these points are translated by
  1103. the lookup table ShadowTab into darker ones.
  1104. If you want to give a sprite a shadow zone, then you must divide your sprite
  1105. into two ones: one building the sprite itself and a second one to realize only
  1106. that shadow area, and compose them with appropriate coordinates.
  1107.  
  1108. Technically spoken, there are short code areas in ANIVGA's routines reserved in
  1109. which the right piece of code to transfer/interpret the sprite's data become
  1110. copied, when not already there. For optimal performance it is wise to group the
  1111. entries in SpriteN[] such that adjacent sprite entries share the same display
  1112. method.
  1113.  
  1114. See also   : convex, concave
  1115.  
  1116.  
  1117. DUMP_SPR - utility
  1118. ──────────────────
  1119.  
  1120. (This is surely a tool for all those hackers among us...)
  1121. If you want to take a closer look at a sprite's data, you don't have to fiddle
  1122. around with DEBUG or the like, just use this sprite dumper: it takes a (binary)
  1123. sprite file (*.COD or *.LIB) and disassembles it into readable ASCII-text.
  1124. You can redirect the output to a file or printer, e.g.:
  1125.  
  1126.  DUMP_SPR mysprite.cod >mysprite.txt
  1127.  
  1128. would dump the sprite file "mysprite.cod" to the ASCII-text file "mysprite.txt"
  1129. for further usage.
  1130. Note that DUMP_SPR creates a format which will be understood by assemblers like
  1131. MASM or TASM so that you can reassemble the files to get a binary sprite file
  1132. once again!
  1133.  
  1134.  
  1135. ERROR - variable
  1136. ────────────────
  1137.  
  1138. Function   : Holds the code of the last error which occured
  1139.  
  1140. Declaration: VAR ERROR:BYTE
  1141.  
  1142. Description: If an error occurs while executing one of its routines, ANIVGA
  1143.              terminates that routine and sets ERROR accordingly to reflect that
  1144.              error.
  1145.              You can use GetErrorMessage() anytime to get more information,
  1146.              which error occured.
  1147.              It is your responsibility to check if such an error occured and
  1148.              react in an appropriate way.
  1149.              For the possible values and their descriptions returned by
  1150.              GetErrorMessage, see there.
  1151.              
  1152. Note (!)   : - After processing an error, you have to reset the variable back
  1153.                to Err_None yourself"
  1154.              - In respect of future extensions, you should treat every value
  1155.                <> Err_None as an error
  1156.              - The most frequented routine Animate() doesn't produce any
  1157.                errors, neither do several other procedures. As a basic rule,
  1158.                all routines which have to do with file I/O have to be checked.
  1159.              - ERROR is initialized with Err_None
  1160.  
  1161. See also   : GetErrorMessage, InitRoutines
  1162.  
  1163.  
  1164. FillBackground - procedure
  1165. ──────────────────────────
  1166.  
  1167. Function   : Fills the background page with the specified color.
  1168.  
  1169. Declaration: {$F+} PROCEDURE FillBackground(color:BYTE); {$F-}
  1170.  
  1171. Description: The given value is written into the whole graphic page BACKGNDPAGE
  1172.              and thus defines the picture before all animations take place to
  1173.              have one color.
  1174.  
  1175. Note       : Use of this routine only makes sense when using background mode
  1176.              STATIC!
  1177.  
  1178. See also   : Background, BACKGNDPAGE, BACKGNDADR, GetBackgroundFromPage,
  1179.              LoadBackgroundPage
  1180.  
  1181.  
  1182. FillPage - procedure
  1183. ────────────────────
  1184.  
  1185. Function   : Fills a graphic page completely with a given color
  1186.  
  1187. Declaration: {$F+} PROCEDURE FillPage(pa,color:Byte); {$F-}
  1188.  
  1189. Description: If you want to paint a complete page uniformly with one color,
  1190.              then this will be the fastest method to do it: specify the graphic
  1191.              page (0,1 or BACKGNDPAGE (=2)) in "pa" and the color to be used in
  1192.              "color".
  1193.  
  1194. Note       : - Although possible, you are strongly discouraged to use this pro-
  1195.                cedure in background mode SCROLLING (i.e.: pa=SCROLLPAGE (=3) as
  1196.                page number), because the background is treated completely dif-
  1197.                ferent!
  1198.              - Remember also that changes to one of the drawing pages (0 or 1)
  1199.                have to be applied _after_ calling Animate and will be visible
  1200.                for exactly one animation cycle, whereas changes to the back-
  1201.                ground page remain permanent (and are best done _before_ calling
  1202.                Animate, although that's not peremptory).
  1203.              - This routine is great to produce "flashing" screens: apply it to
  1204.                1-PAGE (the visible page).
  1205.              - Possible ERROR-values returned are Err_InvalidPageNumber
  1206.  
  1207. See also   : background, How ANIVGA works, LoadPage, LoadBackgroundPage,
  1208.              GetBackgroundFromPage
  1209.  
  1210.  
  1211. FontOrient, FontHeight, FontWidth - type/constants
  1212. ──────────────────────────────────────────────────
  1213.  
  1214. Function   : Supply some additional data about the internal font
  1215.  
  1216. Declaration: TYPE  FontOrient=(horizontal,vertical);
  1217.              CONST FontHeight=6;
  1218.                    FontWidth=6;
  1219.  
  1220. Description: The internal font used for displaying graphic text (OutTextXY(),
  1221.              BackgroundOutTextXY()) can be displayed either horizontally or
  1222.              vertically; use of the TYPE FontOrient simplifies that.
  1223.              To compute the width/height of a text, the constants FontHeight
  1224.              and FontWidth can be used, which specify the size of one letter.
  1225.  
  1226. Note       : -
  1227.  
  1228. See also   : OutTextXY, BackgroundOutTextXY
  1229.  
  1230.  
  1231. GetBackgroundFromPage - procedure
  1232. ─────────────────────────────────
  1233.  
  1234. Function   : Take over one of the drawing pages as background image
  1235.  
  1236. Declaration: {$F+} PROCEDURE GetBackgroundFromPage(pa:Byte); {$F-}
  1237.  
  1238. Description: Specify the graphic page (0 or 1) from which the image should be
  1239.              "captured" and the routine will copy its contents into the back-
  1240.              ground page BACKGNDPAGE (=2) as new background image.
  1241.  
  1242. Note       : - Use of the routine only makes sense if STATIC is used as
  1243.                background mode.
  1244.              - Possible ERROR-values returned are Err_InvalidPageNumber
  1245.  
  1246. See also   : LoadBackgroundPage
  1247.  
  1248.  
  1249. GetErrorMessage - function
  1250. ──────────────────────────
  1251.  
  1252. Function   : Returns a description of the last error occured
  1253.  
  1254. Declaration: {$F+} FUNCTION GetErrorMessage:STRING; {$F-}
  1255.  
  1256. Description: Although you can use the ERROR variable directly to evaluate any
  1257.              error and inform the user about it, it is often more comfortable
  1258.              to let ANIVGA do that: GetErrorMessage will give you a string
  1259.              describing the last error which occured in words.
  1260.              The possible string contents and the corresponding ERROR values
  1261.              are:
  1262.  
  1263.               Err_None: 'No Error'
  1264.                No error occured during the routine; this is the variable's
  1265.                initial value
  1266.  
  1267.               Err_NotEnoughMemory: 'Not enough memory available on heap'
  1268.                The program couldn't load sprites or other data to the heap
  1269.  
  1270.               Err_FileIO: 'I/O-error with file'
  1271.                There was an error reading the file; either the file doesn't
  1272.                exist at the path given or it is damaged
  1273.  
  1274.               Err_InvalidSpriteNumber: 'Invalid sprite number used'
  1275.                This error occurs if you try to load a sprite with a sprite
  1276.                loadnumber not in the valid range 1..LoadMAX
  1277.  
  1278.               Err_NoSprite: 'No (or corrupted) sprite file'
  1279.                While attempting to interpret the data just read in, ANIVGA
  1280.                found the data not to be in the expected format; either because
  1281.                you used a wrong data file or it is damaged
  1282.  
  1283.               Err_InvalidPageNumber: 'Invalid page number used'
  1284.                There are four graphic pages, numbered 0..3. Page 0 & 1 are
  1285.                used for the animation itself, page 2 ("BACKGNDPAGE") holds the
  1286.                static background image and page 3 ("SCROLLPAGE") is reserved
  1287.                for the scrollable background information
  1288.  
  1289.               Err_NoVGA: 'No VGA-card found'
  1290.                The animation package needs a VGA (or compatible) graphic card
  1291.                but couldn't find one
  1292.  
  1293.               Err_NoPicture: 'No (or corrupted) picture file'
  1294.                The background picture file ANIVGA should load has not the ex-
  1295.                pected size/format or a DOS-error occured while attempting to
  1296.                access the data
  1297.  
  1298.               Err_InvalidPercentage: 'Percentage value must be 0..100'
  1299.                If you set the colortable for the shadowing effects of sprite
  1300.                display mode Display_SHADOW, you must use a percentage value
  1301.                giving the remaining brightness of the colors in the shadow
  1302.                areas, which must be in the range 0..100%, of course
  1303.  
  1304.               Err_NoTile: 'No (or corrupted) tile/sprite file'
  1305.                There was an error loading the specified sprite file(s) and
  1306.                interpreting them as background tiles. Most often this occurs
  1307.                because the sprite doesn't meet the requirement to be a multiple
  1308.                of 16 points in its x- and y-directions!
  1309.  
  1310.               Err_InvalidTileNumber: 'Invalid tile number used'
  1311.                There may be only 256 background tiles, numbered 0..255
  1312.  
  1313.               Err_InvalidCoordinates: 'Invalid coordinates used'
  1314.                The virtual background coordinates you use must lie in the range
  1315.                (BackX1,BackY1)..(BackX2,BackY2), which has been specified with
  1316.                SetBackgroundScrollRange()
  1317.  
  1318.               Err_BackgroundToBig: 'Background too big for tile-buffer'
  1319.                ANIVGA's tile buffer can hold no more than MaxTiles (=10000)
  1320.                tiles, that is an area of 10000*16*16 pixels². Check the area
  1321.                you specified in your SetBackgroundScrollRange()-call!
  1322.  
  1323.               Err_InvalidMode: 'Only STATIC or SCROLLING allowed here'
  1324.                The only background modes ANIVGA knows are STATIC and SCROLLING
  1325.  
  1326.               Err_InvalidSpriteLoadNumber: 'Invalid spriteload number used'
  1327.                spriteLOADNumbers must lie in the range 0..LoadMAX; when you
  1328.                get this error, you probably confounded a spriteLOADnumber with
  1329.                a spritenumber
  1330.  
  1331.               (else): 'Unknown error'
  1332.                If ERROR has none of the above values, this string will be
  1333.                returned; this should never happen, though.
  1334.  
  1335. Note       : Calling GetErrorMessage won't set back the ERROR variable either;
  1336.              you must do that explicitly!
  1337.  
  1338. See also   : ERROR
  1339.  
  1340.  
  1341. GetImage - function
  1342. ───────────────────
  1343.  
  1344. Function   : Makes a copy of the specified screen region
  1345.  
  1346. Declaration: {$F+} FUNCTION GetImage(x1,y1,x2,y2:INTEGER;pa:BYTE):POINTER; {$F-}
  1347.  
  1348. Description: - This function works much the same as its equivalent in Turbo-
  1349.                Pascal: (x1,y1) and (x2,y2) define the upper left and lower right
  1350.                corners of the screen part to save, but now these coordinates are
  1351.                _virtual coordinates_, the routine reserves the memory needed to
  1352.                hold the copy itself and you can specify the graphic page, from
  1353.                which the image is to be taken (pa=0,1 or BACKGNDPAGE (=2) ).
  1354.              - As result you get a pointer to the start of the saved image,
  1355.                which can be used with PutImage().
  1356.              - If there is not enough memory available or the specified part of
  1357.                the screen lies completely outside the visible screen, NIL is
  1358.                returned.
  1359.              - Besides that, there are 5 global variables which are set accor-
  1360.                dingly:
  1361.                was_cut:BOOLEAN = TRUE/FALSE, if the image had to be _partially_
  1362.                        clipped (if the specified image is totally offscreen,
  1363.                        was_cut stays at FALSE!)
  1364.                left_cut, right_cut, top_cut, bottom_cut:WORD  hold the size how
  1365.                        much had to be clipped off at the boundaries; these
  1366.                        values are only set when was_cut=TRUE
  1367.                (If you wonder about this odd definitions: GetImage was intended
  1368.                 to work only with the visible screen (that is: with _absolute_
  1369.                 coordinates): together with its counterpart PutImage(), you can
  1370.                 copy a part of the screen to another part or page. In that case,
  1371.                 you do not have to fiddle around with clipping: just issue a
  1372.                 GetImage() and use PutImage() to paste this block elsewhere.
  1373.                 But there may be some applications, when you cut out part of
  1374.                 the screen and think you got the complete graphic figure you
  1375.                 wanted, although (because of the use of virtual coordinates and
  1376.                 your figure being partially offscreen) you got only part of it.
  1377.                 Checking "was_cut" informs you about such a partial clipping.
  1378.                 If your figure is completely offscreen, that is a special case:
  1379.                 it depends on your application whether this should be treated
  1380.                 as being okay or not; if you need special treatment (as with
  1381.                 partial clipping), you still can check for this with something
  1382.                 like:
  1383.                 ...
  1384.                 image_ptr:=GetImage(x1,y1,x2,y2,1-PAGE); {1-PAGE=visible page!}
  1385.                 IF ERROR<>Err_None
  1386.                  THEN ... {probably not enough memory}
  1387.                  ELSE IF (was_cut) OR (image_ptr=NIL)
  1388.                        THEN ... {partial or total clipping occured}
  1389.                        ELSE ... {no clipping at all}
  1390.                )
  1391.              - possible ERROR-values returned are: Err_NotEnoughMemory and
  1392.                Err_InvalidPageNumber
  1393.  
  1394. Note       : As already mentioned, GetImage() only works on screen regions in
  1395.              the _absolute_ coordinate range 0..319, 0..199, but expects
  1396.              _virtual_ coordinates!
  1397.  
  1398. See also   : PutImage, coordinates
  1399.  
  1400.  
  1401. GetModeByte - function
  1402. ──────────────────────
  1403.  
  1404. Function   : Returns the actual display method set for a sprite
  1405.  
  1406. Declaration: {$F+} FUNCTION GetModeByte(Sp:WORD):BYTE; {$F-}
  1407.  
  1408. Description: "Sp" specifies the spriteLOADnumber of the sprite from which the
  1409.              user wants to know the display mode. The function will return one
  1410.              of the valid modes Display_NORMAL, Display_FAST or Display_SHADOW.
  1411.  
  1412. Note       : - Again, spriteLOADnumbers are used!
  1413.              - If the LOADnumber given doesn't exist (because no sprite has
  1414.                been loaded with that number), the routine will return
  1415.                Display_UNKNOWN instead.
  1416.  
  1417. See also   : Display modes, SetModeByte
  1418.  
  1419.  
  1420. GetPixel - function
  1421. ───────────────────
  1422.  
  1423. Function   : Reads a pixel's color
  1424.  
  1425. Declaration: {$F+} FUNCTION GetPixel(x,y:INTEGER):BYTE; {$F-}
  1426.  
  1427. Description: Returns the color value of the specified pixel with the virtual
  1428.              coordinates (x,y) on graphic page PAGE. If (x,y) lies offscreen
  1429.              (to be precise: the computed absolute coordinates lie offscreen),
  1430.              then zero (= black) is returned.
  1431.  
  1432. Note       : Be aware that PAGE is the invisible page, not the one you are
  1433.              looking at!
  1434.  
  1435. See also   : coordinates, PAGE, PageGetPixel, PutPixel
  1436.  
  1437.  
  1438. GRAB - utility
  1439. ──────────────
  1440.  
  1441. GRAB allows you to "steal" graphics from other applications and convert them
  1442. into sprite files (*.COD) or background images (*.PIC) for use with ANIVGA.
  1443. This program is a terminate-and-stay-resident (TSR) utility that has to be run
  1444. before starting those applications from which you want to capture graphic
  1445. images.
  1446. Pressing the hotkey CTRL-ALT-G will popup a frame which you can move and resize
  1447. to select the part of the graphic sreen you want to save (if you are not in a
  1448. graphic mode, a graphic mode unknown to GRAB or in a "MSDos critical" situation
  1449. you'll here a beep instead). Use the "i/j/k/m", arrow and "8/6/2/4" keys for
  1450. that task. The space bar will toggle between which corner (the upper left or
  1451. lower right one) will be used for resizing the box. Press ESC anytime to escape
  1452. from GRAB back to your application.
  1453. By default, GRAB starts in sprite capture mode: if you press "s"ave, "w"rite or
  1454. just RETURN, GRAB will generate a sprite file (starting with the file name
  1455. GRAB_000.COD and counting up for following sprites). To get a background image,
  1456. toggle into screen capture mode by pressing "t" (a second "t" will switch back
  1457. to sprite capture mode again), select the screen region wanted and press "s",
  1458. "w" or RETURN to get that part of the screen in the file GRAB_000.PIC (or what-
  1459. ever number is actual then).
  1460. Naturally, you can't resize your frame in the screen capture mode: it stays at
  1461. its initial size of 320x200 points.
  1462.  
  1463. Note that GRAB doesn't save color palettes, but only the actual color values of
  1464. all the pixels selected. Because ANIVGA uses the standard palette of graphic
  1465. mode $13, it is possible that images captured with GRAB may have different col-
  1466. ors when used in MAKES or ANIVGA, whenever the application from which you cap-
  1467. tured changed the standard palette!
  1468.  
  1469. Note also that there is the same restriction for a sprite's size as in MAKES: a
  1470. sprite may be 152x152 points in max.
  1471.  
  1472. As a last point, the usage of GRAB is restricted to all the standard graphic
  1473. modes known by the VGA-BIOS plus the "tweaked" 256 color mode used by ANIVGA
  1474. itself. GRAB uses the BIOS-routines to read and write dots (with the exception
  1475. of the tweaked mode of course) which makes it relatively slow (but reliable).
  1476. As a consequence, you can capture from 16 color or monochrome graphic modes,
  1477. too (although it makes little sense to me capturing 16 or 2 color images for
  1478. usage in a 256 color sprite toolkit...)
  1479.  
  1480. See also   : MAKES
  1481.  
  1482.  
  1483. GraphTextBackground, GraphTextColor, GraphTextOrientation - variables
  1484. ─────────────────────────────────────────────────────────────────────
  1485.  
  1486. Function   : Determine how the OutTextXY()-procedures work
  1487.  
  1488. Declaration:  TYPE  FontChar=ARRAY[0..5] OF BYTE;
  1489.                     Font=ARRAY[0..255] OF Fontchar;
  1490.                     FontOrient=(horizontal,vertical);
  1491.               CONST GraphTextOrientation:FontOrient=horizontal;
  1492.                     GraphTextColor:BYTE=white;
  1493.                     GraphTextBackground:BYTE=white;
  1494.                     FontHeight=6;
  1495.                     FontWidth=6;
  1496.  
  1497. Description: Whenever text is to be written to the graphic screen, ANIVGA
  1498.              consults some global variables. GraphTextColor is simply the color
  1499.              in which the text should be drawn, GraphTextBackground specifies
  1500.              the color for the pixels in between the letters with one special
  1501.              value: if GraphTextBackground=GraphTextcolor, then only the pixels
  1502.              belonging to the letters will be drawn with all others remaining
  1503.              unchanged.
  1504.              Finally, GraphTextOrientation tells ANIVGA in which direction the
  1505.              text should be written with two values being possible: HORIZONTAL
  1506.              (default) for left-to-right text and VERTICAL for top-to-bottom
  1507.              style text.
  1508.  
  1509. Note       : Default color for the text is "white/white" = "white and don't
  1510.              change pixel values between letters".
  1511.  
  1512. See also   : OutTextXY, BackgroundOutTextXY
  1513.  
  1514.  
  1515. HitDetect - function
  1516. ────────────────────
  1517.  
  1518. Function   : Checks whether two sprites collide or not
  1519.  
  1520. Declaration: {$F+} FUNCTION Hitdetect(s1,s2:INTEGER):BOOLEAN; {$F-}
  1521.  
  1522. Description: Call this routine with the sprite numbers of the two sprites to be
  1523.              checked for collision; the function will return TRUE/FALSE when
  1524.              the sprites collide/do not collide, respectively.
  1525.  
  1526. Note (!)   : - Collision detection is independent of whether the sprites are
  1527.                visible or offscreen: ANIVGA uses the corrdinates of the two
  1528.                sprites given (in SpriteX/Y) and internal data to check.
  1529.              - For this it is possible to check for collisions _before_ drawing
  1530.                an image (with Animate) and thus make necessary sprite updates
  1531.                at once!
  1532.              - Inactive sprites cannot collide:
  1533.                (SpriteN[s1] or SpriteN[s2]=0) -> FALSE
  1534.              - A sprite can't collide with itself: (s1=s2 -> FALSE)
  1535.  
  1536. See also   : Collision-detection
  1537.  
  1538.  
  1539. InitGraph - procedure
  1540. ─────────────────────
  1541.  
  1542. Function   : Initialises the VGA card for the use with ANIVGA
  1543.  
  1544. Declaration: {$F+} PROCEDURE InitGraph; {$F-}
  1545.  
  1546. Description: ANIVGA uses a special graphic mode, which supports 4 graphic pages
  1547.              in the resoultion 320x200 pixels and 256 colors. Because this mode
  1548.              is not known by the VGA's BIOS, ANIVGA has to reprogram the VGA.
  1549.              You should use this command only once to switch into graphic mode.
  1550.  
  1551. Note       : InitGraph automatically switches to the invisible graphic page
  1552.              1-PAGE.
  1553.  
  1554. See also   : Screen, CloseRoutines
  1555.  
  1556.  
  1557. InitRoutines - procedure
  1558. ────────────────────────
  1559.  
  1560. Function   : Resets all necessary internal variables of ANIVGA to initial values
  1561.  
  1562. Declaration: {$F+} PROCEDURE InitRoutines {$F-}
  1563.  
  1564. Description: At program start, some variables have to be set and a few system
  1565.              checks are necessary.
  1566.              Among these are:
  1567.              - SpriteN[] and SpriteAd[] become cleared (= set to 0)
  1568.              - Page (the actual drwaing page) is set to 0
  1569.              - PageAdr is set to the segment address of the drawing page PAGE
  1570.              - BackgroundMode is set to STATIC, i.e.: non-scrollable background
  1571.              - BackGndAdr is set to the segment address of the background image
  1572.              - StartVirtualX/Y are set to (0,0), making the normal screen coor-
  1573.                dinates identical to the virtual screen coordinates
  1574.              - the old graphic/text mode which was active at program start is
  1575.                stored for restoring it at the program end
  1576.              - the system is checked if a VGA card is present and the global
  1577.                variable ERROR is set accordingly
  1578.              - CycleTime is set to 0, which says that there should be no time-
  1579.                control mechanism for the animation rate
  1580.              - if the machine is not at least an AT, the time mechanism is
  1581.                switched off completely
  1582.              - COLOR is set to 15 (= white)
  1583.  
  1584.              The first thing you should do in your programs is to look at the
  1585.              ERROR variable: if it was set to something different from Err_None
  1586.              (by the implicit, automatical call of InitRoutines) then your pro-
  1587.              gram should no proceed further.
  1588.  
  1589. Note       : - This routine is called automatically at the very beginning of
  1590.                every program which uses ANIVGA. For that, there is normally no
  1591.                need to call this routine explicitly.
  1592.              - Possible ERROR-values returned are: Err_None and Err_NoVGA
  1593.              - Note that this is the _only_ routine that definitely sets the
  1594.                variable ERROR, either to Err_None or Err_NoVGA. Because it is
  1595.                called at the beginning of every program, it is thus assured
  1596.                that your application always has a defined value for ERROR!
  1597.  
  1598. See also   : ERROR
  1599.  
  1600.  
  1601. Line - procedure
  1602. ────────────────
  1603.  
  1604. Function   : Draw a line between the two points specified
  1605.  
  1606. Declaration: {$F+} PROCEDURE Line(x1,y1,x2,y2:INTEGER; pa:BYTE); {$F-}
  1607.  
  1608. Description: Calling this routine will draw a line between the two points
  1609.              (x1,y1) and (x2,y2) on graphic page "pa" and in the color COLOR.
  1610.              The routine uses virtual coordinates and clips the line down to
  1611.              its visible part.
  1612.              "pa" must be one of the values 0, 1 or BACKGNDPAGE (=2).
  1613.  
  1614. Note       : - As with all point-setting procedures of ANIVGA, you have to re-
  1615.                member ANIVGA's working scheme: the first thing ANIVGA does when
  1616.                Animate becomes executed is to copy the background image to the
  1617.                actual drawing page PAGE, erasing everything on that image.
  1618.                For this reason, a line drawn on the visible page 1-PAGE will be
  1619.                visible exactly one animation cycle.
  1620.              - Possible ERROR-values returned are: Err_InvalidPageNumber
  1621.  
  1622. See also   : PutPixel, BackGroundLine, coordinates
  1623.  
  1624.  
  1625. LoadBackgroundPage - function
  1626. ─────────────────────────────
  1627.  
  1628. Function   : Loads a background image from disk
  1629.  
  1630. Declaration: {$F+} PROCEDURE LoadBackgroundpage(name:String) {$F-}
  1631.  
  1632. Description: This routine loads a bitmap image stored in file "name" into the
  1633.              graphic page used for the background image (BACKGNDPAGE).
  1634.  
  1635. Note (!)   : - This routine must be called *after* the graphic mode has been
  1636.                initialized (with InitGraph())!
  1637.              - You can create such images either with the WritePage()- and
  1638.                WriteBackgroundPage()-routines of ANIVGA or the GRAB-Utility.
  1639.              - Calling this routine is equivalent to use the routine LoadPage()
  1640.                with BACKGNDPAGE as second argument.
  1641.              - Possible ERROR-values returned are: Err_FileIO and Err_NoPicture
  1642.  
  1643. See also   : Background, LoadPage, FillBackground, GetBackgroundFromPage,
  1644.              InitGraph
  1645.  
  1646.  
  1647. LoadMAX - constant
  1648. ──────────────────
  1649.  
  1650. Function   : Specifies the maximum number of different sprites
  1651.  
  1652. Declaration: CONST LoadMAX=1000;
  1653.  
  1654. Description: For each physical sprite, ANIVGA uses an internal pointer to its
  1655.              data. There are LoadMAX pointers, thus there may be up to LoadMAX
  1656.              different spriteLOADnumbers (= different sprites).
  1657.  
  1658. Note       : Don't mix this constant up with NMAX!
  1659.  
  1660. See also   : NMAX, SPRITE, SpriteLOADnumbers, Spritenumbers
  1661.  
  1662.  
  1663. LoadPage - procedure
  1664. ────────────────────
  1665.  
  1666. Function   : Loads a graphic page from disk
  1667.  
  1668. Declaration: {$F+} PROCEDURE LoadPage(name:STRING; pa:BYTE); {$F-}
  1669.  
  1670. Description: "name" is the MSDOS-path to the graphic image to load, pa the
  1671.              destination page (0,1 or BACKGNDPAGE (=2)).
  1672.  
  1673. Note       : - The graphic mode must have been initialized (vià InitGraph)
  1674.                already!
  1675.              - You can generate disk files of graphic pages with the help of
  1676.                the WritePage()-routine or with the GRAB-utility program.
  1677.              - Don't use this routine to load an image into the SCROLLPAGE,
  1678.                i.e.: in background mode SCROLLING!
  1679.              - Possible ERROR-values returned are: Err_InvalidPageNumber,
  1680.                Err_FileIO and Err_NoPicture
  1681.  
  1682. See also   : GRAB, WritePage, background, InitGraph
  1683.  
  1684.  
  1685. LoadSprite - function
  1686. ─────────────────────
  1687.  
  1688. Function   : Loads one (or more) sprites into memory
  1689.  
  1690. Declaration: {$F+} FUNCTION LoadSprite(name:String; number:WORD):WORD; {$F-}
  1691.  
  1692. Description: "name" is the MSDOS-name of the sprite file to load, which can be
  1693.              either a single sprite file (*.COD) or a complete sprite library
  1694.              (*.LIB): the function will detect automatically, which format is
  1695.              used while loading the data.
  1696.              "number" is the spriteLOADnumber, the first loaded sprite will be
  1697.              assigned to. If the file contains more than one sprite, they will
  1698.              get consecutive LOADnumbers.
  1699.              The value returned by the function is the numbers of sprites read
  1700.              in (i.e.: 0 means "no sprite read", so you should check ERROR in
  1701.              that case).
  1702.  
  1703. Note       : - Unlike LoadTile(), LoadSprite() loads data into conventional
  1704.                memory. For that, you don't have to be in graphic mode to load
  1705.                data from disk!
  1706.              - Possible ERROR-values returned are: Err_FileIO, Err_NoSprite,
  1707.                Err_NotEnoughMemory and Err_InvalidSpriteNumber
  1708.  
  1709. See also   : sprite format, MAKES
  1710.  
  1711.  
  1712. LoadTile - function
  1713. ───────────────────
  1714.  
  1715. Function   : Loads one or more tiles from disk
  1716.  
  1717. Declaration: {$F+} FUNCTION LoadTile(name:STRING; number:BYTE):WORD; {$F-}
  1718.  
  1719. Description: This routine loads the background tile file "name" into the
  1720.              graphic memory area reserved for tiles (the SCROLLPAGE).
  1721.              The starting number for the first tile of the file is "number",
  1722.              if there are more than one tile in the named file, they will be
  1723.              loaded too (with increasing numbers).
  1724.              The function returns the number of tiles read in.
  1725.  
  1726. Note (!)   : - This routine must be called *after* the graphic mode has been
  1727.                initialized (with InitGraph)!
  1728.                What the function actually does is reading in a sprite and con-
  1729.                verting it into an internal tile format: if the sprite read in
  1730.                doesn't have the proper size of a tile (16x16 pixels), you nor-
  1731.                mally will get an appropriate error (Err_NoTile), with one (use-
  1732.                ful) exception: if the sprite can be "cut" into tiles (that is,
  1733.                its width and height are multiples of 16 pixels each), then
  1734.                LoadTile() will do so with the following numbering scheme: from
  1735.                left to right and from top to bottom.
  1736.                For example, a sprite with (width,height)=(3*16,2*16) points
  1737.                would be numbered as: (assuming that "number" = 0)
  1738.                ┌────────┬────────┬────────┐
  1739.                │        │        │        │
  1740.                │   0    │   1    │   2    │
  1741.                │        │        │        │
  1742.                ├────────┼────────┼────────┤
  1743.                │        │        │        │
  1744.                │   3    │   4    │   5    │
  1745.                │        │        │        │
  1746.                └────────┴────────┴────────┘
  1747.                Besides, LOADTILE can load a sprite library, too (they will be
  1748.                loaded in the sequence in which they appear in the library).
  1749.              - Possible ERROR-values returned are: Err_NotEnoughMemory,
  1750.                Err_FileIO, Err_NoTile and Err_InvalidTileNumber
  1751.  
  1752. See also   : Background, LOADSPRITE, TILE
  1753.  
  1754.  
  1755. MAKES - utility
  1756. ───────────────
  1757.  
  1758. The design of sprites is much to tedious to be carried out manually. For this
  1759. reason, there are two utility programs to simplify that task. The first one
  1760. is a resident program named "GRAB" to capture graphics from other applications
  1761. and convert them into sprites, the second is MAKES, a _simple_ spritemaker
  1762. program (don't expect too much).
  1763. To use it, you must have a mouse installed (and a VGA card, of course).
  1764. (Other than ANIVGA itself, the program uses the "normal" 256-color mode $13, so
  1765.  a MCGA-adapter should work also)
  1766. There are no parameters or such things, just start it!
  1767. In the upper right region of the screen there is the so called "work area", in
  1768. which you can paint your sprite pixelwise.
  1769. At the bottom of the screen, all possible colors are available. To choose one,
  1770. point at the color wanted and press the mouse button, to which you want this
  1771. color assigned.
  1772. All other options are so simple that there should be no descriptions necessary,
  1773. so that I only give some general infos here:
  1774. Note that sprites are always stored as the smallest rectangle which surrounds
  1775. them and starts at the upper left corner (0,0): if you don't have special
  1776. reasons to do otherwise, your sprites should start in the upper left corner.
  1777. If for example you realize a sprite consisting of one single point at coordi-
  1778. nates (a,b), the smallest surrounding box with (0,0) as upper left corner would
  1779. be
  1780.    (0,0)      (a,0)      of size (a+1)*(b+1) pixels (=bytes)!!!
  1781.      ┌──────────┐
  1782.      │          │
  1783.      │          │
  1784.      │          │
  1785.      └──────────▀   <─ this is your 1 point
  1786.    (0,b)      (a,b)
  1787.  
  1788. To determine what areas belong to your sprite and which don't, the program
  1789. assumes color 0 to specify no-sprite-areas and all other colors to be part of
  1790. your sprite (roughly spoken).
  1791.  
  1792. The best way to design a sprite is to start with a cleared work area and draw
  1793. the sprite in the midst of it. If you think you're done, use the direction
  1794. boxes to align your sprite with the upper left corner. Then click on the
  1795. "boundaries" option ("see transparent?": no) to see the sprite's size and
  1796. extension in the x/y-directions. This is useful to find very dark points with
  1797. color<>0 set accidentally which would extend the sprite size unnecessarily.
  1798. If you are unsure whether you can use display mode "Display_FAST" or not, call
  1799. "boundaries" a second time and select "see transparent?" _yes_ this time: if
  1800. the blinking white parts "spread" out of the parts you think your sprite should
  1801. be made of, then you should use "Display_NORMAL", if all the blinking areas are
  1802. inside your sprite, you can use "Display_FAST".
  1803.  
  1804. Note: - The maximal size for your sprites developped this way is 152x152 points
  1805.         (that is only because of the restricted size of the work area on your
  1806.          screen; ANIVGA itself can handle sprites up to 32000 pixels in each
  1807.          axis or 64K max. size)
  1808.       - For more complex sprites, it is often easier to use a commercial pain-
  1809.         ting program, capture the sprite with GRAB and edit the resulting
  1810.         sprite with MAKES
  1811.  
  1812. See also: sprite format, GRAB, Display modes
  1813.  
  1814.  
  1815. MaxTiles - constant
  1816. ───────────────────
  1817.  
  1818. Function   : Holds the maximum number of tiles to build the background image
  1819.  
  1820. Declaration: CONST MaxTiles=10000;
  1821.  
  1822. Description: In background mode SCROLLING, you may use up to MaxTiles tiles
  1823.              to build your graphic image.
  1824.  
  1825. Note       : -
  1826.  
  1827. See also   : Background
  1828.  
  1829.  
  1830. NextSprite - variables
  1831. ──────────────────────
  1832.  
  1833. Function   : Holds the "successors" of sprites for sprite cycles
  1834.  
  1835. Declaration: VAR NextSprite: ARRAY [0..LoadMAX] OF WORD
  1836.  
  1837. Description: To realize a sprite cycle, you must tell ANIVGA which sprites
  1838.              should be drawn one after another. It is this information
  1839.              NextSprite holds! For example, let us assume that you wanted to
  1840.              make the sprite(loadnumber)s 43, 177 and 111 a sprite cycle, i.e.:
  1841.              whenever you set a sprite (to be precise: a SpriteN[]-entry) to
  1842.              one of these three numbers, ANIVGA should cycle between the three
  1843.              sprite-images in the sequence 43->177->111->43->177->111->...
  1844.              You would then set NextSprite[43]:=177; NextSprite[177]:=111 and
  1845.              NextSprite[111]:=43  (don't forget this final value!) to do so.
  1846.  
  1847. Note (!)   : - Most often, you will have the situation that some sprite(load)-
  1848.                numbers with consecutive numbers should make up a cycle. In that
  1849.                case it is more convenient to use the SetSpriteCycle()-procedure
  1850.                to do the job for you
  1851.              - Again, note that the routine deals with spriteLOADnumbers! That
  1852.                is intentionally, because a sprite cycle is related to the
  1853.                _physical_ existent sprite data, or simply spoken: if you make
  1854.                5 pictures to form a flickering torch and you are going to use
  1855.                10 torches in your animation then each of them should loop
  1856.                through this 5-picture-cycle, shouldn't it?
  1857.              - NextSprite[] is initially set "to point to itself", that is:
  1858.                NextSprite[i]=i for all possible i's. If you had to break off
  1859.                a sprite cycle (though I can't think what this should be good
  1860.                for...), you must restore this data, e.g.: if you wanted to
  1861.                break the sprite cycle above, you would have to set
  1862.                NextSprite[43]:=43; NextSprite[177]:=177; NextSprite[111]:=43;
  1863.              - As this is a global variable, ANIVGA can't check whether your
  1864.                settings make sense or not; thus, it remains your responsibility
  1865.                to use proper values!
  1866.  
  1867. See also   :   SetSpriteCycle, Sprite cycles
  1868.  
  1869.  
  1870. NMAX - constant
  1871. ───────────────
  1872.  
  1873. Function   : Determines the maximum of sprites to be active at the same time
  1874.              (minus 1)
  1875.  
  1876. Declaration: CONST NMAX=499
  1877.  
  1878. Description: This constant sets the size of the internal tables - and thus the
  1879.              valid sprite numbers: the indices of the tables SpriteX, SpriteY
  1880.              and SpriteN must lie in the range 0..NMAX.
  1881.              To state it otherwise, there may be up to NMAX+1 sprites creeping
  1882.              around your screen at the same time...
  1883.  
  1884. Note       : Don't confound that constant with LoadMAX
  1885.  
  1886. See also   : LoadMAX
  1887.  
  1888.  
  1889. OutTextXY - procedure
  1890. ─────────────────────
  1891.  
  1892. Function   : Writes a textstring to the graphic screen
  1893.  
  1894. Declaration: {$F+} PROCEDURE OutTextXY(x,y:INTEGER; pa:BYTE; s:STRING); {$F-}
  1895.  
  1896. Description: ANIVGA has a built-in font, each character consisting of 6x6
  1897.              pixels: very ugly, but hey, we want to make animations, not text!
  1898.              To write the string "s" to the graphic screen, you must specify
  1899.              the upper left starting corner of the text in (x,y):
  1900.                  (x,y) -> ▄──────────┐ , where (x,y) are virtual coordinates!
  1901.                           │          │
  1902.                           │          │
  1903.                           │          │
  1904.                           └──────────┘
  1905.              The text will be drawn in color GRAPHTEXTCOLOR and with the orien-
  1906.              tation GRAPHTEXTORIENTATION ("VERTICAL" or "HORIZONTAL").
  1907.              A third global variable, GRAPHTEXTBACKGROUND, specifies the color
  1908.              which will be used for the background area "beneath" the text
  1909.              letters; if GRAPHTEXTCOLOR=GRAPHTEXTBACKGROUND then the text will
  1910.              be drawn like TurboPascal's routine does: only the pixels be-
  1911.              longing to the letters will be drawn, all others remain unchanged.
  1912.              "pa" specifies the graphic page to be drawn on and must be one of
  1913.              the drawing pages (0 or 1) or the BACKGNDPAGE (=2) for background
  1914.              mode STATIC.
  1915.  
  1916. Note       : - Better fonts could have been developped, but they would all
  1917.                depend on special assumptions about the text- and/or background
  1918.                color(s).
  1919.                This font was intented for short and simple text strings and to
  1920.                be as small as possible.
  1921.                Nevertheless, using a bigger cell (say: 10x10) and several
  1922.                colors (for antialiasing effects) can result in very impressive
  1923.                fonts - and work, too...
  1924.              - Possible ERROR-values returned are: Err_InvalidPageNumber
  1925.  
  1926. See also   : GraphtextColor, GraphtextOrientation, GraphtextBackground,
  1927.              BackgroundOutTextXY
  1928.  
  1929.  
  1930. PAGE - variable
  1931. ───────────────
  1932.  
  1933. Function   : Holds the number of the actual drawing page
  1934.  
  1935. Declaration: VAR PAGE:WORD
  1936.  
  1937. Description: ANIVGA uses a page flipping approach. Basically this means that it
  1938.              alternates between using page 0 and page 1 for its display.
  1939.              Although this mechanism should be transparent for the user, ANIVGA
  1940.              provides you with the page number of the actual drawing page in
  1941.              "PAGE". Note that this number specifies always the invisible page:
  1942.              when PAGE=0, then the actual _displayed_ page is page 1 and vice
  1943.              versa (ANIVGA always works on the invisible page!).
  1944.  
  1945. Note (!)   : Only _read_ this value, never assign a new value to it!
  1946.  
  1947.  
  1948. PAGEADR - variable
  1949. ──────────────────
  1950.  
  1951. Function   : Holds the segment address of the actual drawing page PAGE
  1952.  
  1953. Declaration: VAR PAGEADR:WORD
  1954.  
  1955. Description: As already mentioned, there are four graphic pages, numbered from
  1956.              0 to 3. The start addresses of these four pages are used by ANIVGA
  1957.              and normally the user should not need to reference them, but with
  1958.              PAGEADR at least the address of the actual (invisble) graphic page
  1959.              PAGE is available in PAGEADR.
  1960.  
  1961. Note (!)   : Only use this variable to _read_ its value, never change it!
  1962.              Although this 16-bit-value represents only the segment part of the
  1963.              complete address, it is the whole address: the address is norma-
  1964.              lized in such a way that the offset part is always zero.
  1965.  
  1966. See also   : PAGE
  1967.  
  1968.  
  1969. PageGetPixel - function
  1970. ───────────────────────
  1971.  
  1972. Function   : Returns the color value of the specified point
  1973.  
  1974. Declaration: {$F+} FUNCTION PageGetPixel(x,y:INTEGER; pa:BYTE):BYTE; {$F-}
  1975.  
  1976. Description: If the point at the virtual coordinates (x,y) and graphic page
  1977.              "pa" lies on the screen (i.e.: in the range (0,0)..(319,199) in
  1978.              absolute coordinates), this routine will return its color, if it
  1979.              is offscreen, the function returns zero.
  1980.              "pa" should be one of the values 0, 1 or BACKGNDPAGE (=2).
  1981.  
  1982. Note       : - If you want to read a pixels' color from the _visible_ page, you
  1983.                have to remember that it is the opposite of the _actual_ page
  1984.                (that is, you have to use "1-PAGE" as page number).
  1985.              - Although only values of 0,1 and BACKGNDPAGE (=2) make sense as
  1986.                "pa" values, the routine doesn't check that (for improved speed)
  1987.              - For that, the routine _doesn't_ return Err_InvalidPagenumber or
  1988.                something similiar in ERROR!
  1989.  
  1990. See also   : Background, Coordinates, GetPixel
  1991.  
  1992.  
  1993. PagePutPixel - procedure
  1994. ────────────────────────
  1995.  
  1996. Function   : Plots a point at a specified page
  1997.  
  1998. Declaration: {$F+} PROCEDURE PagePutPixel(x,y:INTEGER; color,pa:BYTE); {$F-}
  1999.  
  2000. Description: This routine is very similiar to PutPixel(), but it lets you
  2001.              specify explicitly on which graphic page the point shall be drawn.
  2002.              (x,y) specify the virtual coordinates of the point to be drawn in
  2003.              color "color". If this point lies onscreen (i.e.: its absolute
  2004.              coordinates are between (0,0)..(319,199)), it will be drawn on the
  2005.              specified page "pa", which must have one of the values 0, 1 or
  2006.              BACKGNDPAGE (=2). The latter only makes sense if STATIC is used as
  2007.              background mode.
  2008.  
  2009. Note       : - Don't forget that this routine works with virtual coordinates.
  2010.              - Note also that the point is _not_ drawn automatically on the
  2011.                background page if pa=0 or pa=1, thus it will be visible exactly
  2012.                one animation cycle (and be overdrawn by the background image
  2013.                then).
  2014.              - Because of ANIVGA's working scheme, you probably want to use
  2015.                this routine AFTER calling Animate() (else, your point would be
  2016.                overdrawn by the background image immediately) if pa=1-PAGE.
  2017.                If you want to draw the point at the _visible_ page, remember
  2018.                that it is the "opposite" of the _actual_ drawing page, i.e.:
  2019.                you have to use "1-PAGE" for "pa".
  2020.              - For improved speed, the routine _doesn't_ check the "pa"
  2021.                variable to have a valid value, so there will be no report to
  2022.                ERROR (Err_InvalidPageNumber or the like) available!
  2023.                It remains your responsibility to assure a proper value for pa!
  2024.  
  2025. See also   : BackgroundPutPixel, PutPixel, coordinates, How ANIVGA works
  2026.  
  2027.  
  2028. PutImage - procedure
  2029. ────────────────────
  2030.  
  2031. Function   : Pastes a formerly copied image to the screen
  2032.  
  2033. Declaration: {$F+} PROCEDURE PutImage(x,y:INTEGER; p:POINTER; pa:WORD); {$F-}
  2034.  
  2035. Description: PutImage() is the counterpart of GetImage(): use GetImage() to
  2036.              copy part of the screen and PutImage to paste it somewhere. (x,y)
  2037.              is the upper left corner of the destination (in _virtual_ coordi-
  2038.              nates), "p" is the pointer given by GetImage() and "pa" is the
  2039.              number of the graphic page (0, 1 or BACKGNDPAGE (=2)) of the des-
  2040.              tination.
  2041.              If p equals NIL, the routine does nothing at all; this is useful
  2042.              because you can PutImage() directly on the result of a GetImage()
  2043.              call without further checking for clippings.
  2044.  
  2045. Note       : - Like GetImage(), this routine also works only when the _virtual_
  2046.                coordinates translate into _absolute_ coordinates in the range
  2047.                of 0..319, 0..199, that is: they must lie on the visible part of
  2048.                the screen, everything else is clipped off.
  2049.              - Possible ERROR-values returned are: Err_InvaliPageNumber
  2050.  
  2051. See also   : GetImage, coordinates
  2052.  
  2053.  
  2054. PutPixel - procedure
  2055. ────────────────────
  2056.  
  2057. Function   : Plots a point
  2058.  
  2059. Declaration: {$F+} PROCEDURE PutPixel(x,y:INTEGER; color:BYTE); {$F-}
  2060.  
  2061. Description: (x,y) specify the virtual coordinates of the point to be drawn in
  2062.              color "color". If this point lies onscreen (i.e.: its absolute
  2063.              coordinates are between (0,0)..(319,199)), it will be drawn on the
  2064.              visible page 1-PAGE.
  2065.  
  2066. Note       : This routine is not the same as TurboPascal's one: it works with
  2067.              virtual coordinates! Note also that the point is _not_ drawn on
  2068.              the background page, thus it will be visible for exactly one ani-
  2069.              mation cycle (and be overdrawn by the background image then).
  2070.              Because of ANIVGA's working scheme, you probably want to use this
  2071.              routine AFTER calling Animate() (your point will then be visible
  2072.              until the next call to Animate()).
  2073.  
  2074. See also   : BackgroundPutPixel, PagePutPixel, coordinates, How ANIVGA works
  2075.  
  2076.  
  2077. PutTile - procedute
  2078. ───────────────────
  2079.  
  2080. Function   : "Pastes" a tile into the background image
  2081.  
  2082. Declaration: {$F+} PROCEDURE PutTile(x,y:INTEGER; TileNr:BYTE); {$F-}
  2083.  
  2084. Description: After you have defined a background scrolling area, you can use to
  2085.              PutTile() to arrange them as wanted to build your background image.
  2086.              (x,y) is the virtual coordinate where you want the tile "TileNr"
  2087.              to be placed.
  2088.              (x,y) will be changed to be a multiple on 16 in each direction
  2089.              and must then lie in the range (BackX1,BackY1)..(BackX2,BackY2).
  2090.  
  2091. Note       : - Of course, this routine only makes sense when you use background
  2092.                mode SCROLLING!
  2093.              - (x,y) will be drawn to the upper left to fall on the grid.
  2094.              - Possible ERROR-values returned are: Err_InvalidCoordinates
  2095.  
  2096. See also   : background, tile, SetBackgroundScrollRange, coordinate, BackX1,
  2097.              BackX2, BackY1, BackY2
  2098.  
  2099.  
  2100. Screen - procedure
  2101. ──────────────────
  2102.  
  2103. Function   : Chooses the display page.
  2104.  
  2105. Declaration: {$F+} PROCEDURE Screen(pa:BYTE) {$F-}
  2106.  
  2107. Description: Call Screen() with a value between 0 and 3 which tells the routine
  2108.              to which graphic page it should switch. This is done by repro-
  2109.              gramming the VGA start address registers. For a flickerfree dis-
  2110.              play, this switching is synchronized to the vertical retrace
  2111.              signal.
  2112.  
  2113. Note (!)   : - You should not use this routine if you are not absolutely sure
  2114.                what you are doing! Be aware that ANIVGA relies on the fact that
  2115.                the actual drawing page is PAGE and its segment address is in
  2116.                PAGEADR while the visible page is 1-PAGE!
  2117.              - Although it makes little sense to apply this routine to graphic
  2118.                pages other than 0 or 1, it is possible to set "pa" to 2 (=BACK-
  2119.                GNDPAGE) or 3 (=SCROLLPAGE).
  2120.  
  2121. See also   : PAGE, PAGEADR, InitGraph
  2122.  
  2123.  
  2124. ScrollPage - constant
  2125. ─────────────────────
  2126.  
  2127. Function   : Holds the page number of the backround page
  2128.  
  2129. Declaration: CONST SCROLLPAGE=3;
  2130.  
  2131. Description: When using background mode SCROLLING, BackGndPage specifies the
  2132.              page number of the tile buffer used to build up the background
  2133.              image for animations.
  2134.  
  2135. Note (!)   : Use of this constant only makes sense when using background mode
  2136.              SCROLLING!
  2137.  
  2138. See also   : BackGndPage, Background
  2139.  
  2140.  
  2141. SetBackgroundMode - procedure
  2142. ─────────────────────────────
  2143.  
  2144. Function   : Chooses one of the possible background modes of ANIVGA
  2145.  
  2146. Declaration: {$F+} PROCEDURE SetBackgroundMode(mode:BYTE); {$F-}
  2147.  
  2148. Description: ANIVGA has two possible ways of handling background you can choose
  2149.              of: "STATIC" or "SCROLLING" backgrounds with several advantages
  2150.              and disadvantages, each (see background). Specify the mode you
  2151.              want to use in the "mode" variable.
  2152.  
  2153. Note       : - Default value set by ANIVGA is STATIC.
  2154.              - Possible ERROR-values returned are: Err_InvalidMode
  2155.  
  2156. See also   : background
  2157.  
  2158.  
  2159. SetBackgroundScrollRange - procedure
  2160. ────────────────────────────────────
  2161.  
  2162. Function   : Specifies the scrollable background area in mode SCROLLING
  2163.  
  2164. Declaration: {$F+} PROCEDURE SetBackgroundScrollRange(x1,y1,x2,y2:INTEGER) {$F-}
  2165.  
  2166. Description: (x1,y1) is the upper left corner of the background scroll area,
  2167.              (x2,y2) the lower right corner (all virtual coordinates).
  2168.              ANIVGA will round the points given to fit on a grid with mesh 16,
  2169.              that is, x1,y1,x2,y2 will be changed to be all multiples of 16.
  2170.              These new values will be stored in the (global) variables BackX1,
  2171.              BackY1, BackX2, BackY2 for further use.
  2172.              Besides that, XTiles and YTiles will hold the width and height of
  2173.              the choosen background area in tiles.
  2174.  
  2175. Note       : - You can read the Back??-variables for your information, but
  2176.                don't change them!
  2177.              - Of course, this routine only makes sense when you are going to
  2178.                use SCROLLING as background mode.
  2179.              - The upper left corner (x1,y1) will be drawn to the upper left,
  2180.                the lower right corner (x2,y2) to the lower right to fall on the
  2181.                grid.
  2182.              - Don't forget that the tile memory is limited; you can't select
  2183.                an area bigger than MaxTiles (=10000) tiles, that is more than
  2184.                2560000 pixels².
  2185.              - Possible ERROR-values returned are: Err_InvalidCoordinates and
  2186.                Err_BackgroundToBig
  2187.  
  2188. See also   : background, tiles, PutTile
  2189.  
  2190.  
  2191. SetCycleTime - procedure
  2192. ────────────────────────
  2193.  
  2194. Function   : Defines the maximum animation speed
  2195.  
  2196. Declaration: {$F+} PROCEDURE SetCycleTime(milliseconds:WORD); {$F-}
  2197.  
  2198. Description: There are lots of PC-compatible machines with a broad range of
  2199.              clock rates, wait states and different speeds of their graphic
  2200.              cards. With this routine you can set the time an animation cycle
  2201.              has to last at least: at the very end of Animate, the routine
  2202.              checks whether at least "milliseconds" milliseconds have been past
  2203.              since the last call to this routine and waits if necessary.
  2204.              If you give 0 milliseconds as an argument or your machine is not
  2205.              (at least) an AT class machine, there will be no such time control
  2206.              mechanism and the animation will always take part at the maximal
  2207.              speed on the specific machine (this is also the default value).
  2208.  
  2209.              For example: "SetCycleTime(100);" would restrict the animation
  2210.              rate even on the fastest 80586 machines to at most 1sec/100msec
  2211.              = ten frames per second.
  2212.  
  2213. Note (!)   : - Because there is no such high precision timer on PC/XT computers
  2214.                as required, SetCycleTime() is ignored on these machines.
  2215.                Anyway, this should be not to hard because these computers are
  2216.                normally that slow that they would not have been slowed down
  2217.                either.
  2218.              - The accuracy of this timing mechanism is better than 1 milli-
  2219.                second.
  2220.  
  2221.  
  2222. SetModeByte - procedure
  2223. ───────────────────────
  2224.  
  2225. Function   : Specifies the way a sprite will be displayed
  2226.  
  2227. Declaration: {$F+} PROCEDURE SetModeByte(Sp:WORD; M:BYTE); {$F-}
  2228.  
  2229. Description: This routine assigns one of the possible display methods "M"
  2230.              (Display_NORMAL, Display_FAST, Display_SHADOW) to the specified
  2231.              spriteLOADnumber "Sp".
  2232.  
  2233. Note       : - Because this kind of information is stored directly inside the
  2234.                sprite data, the sprite must have been loaded already for this
  2235.                action to work.
  2236.              - For the same reason, this routine works on spriteLOADnumbers,
  2237.                not sprite numbers (>gee, again!<): a display method set for one
  2238.                spriteLOADnumber will affect all sprites with that LOADnumber!
  2239.                Most often, that is okay (e.g.: if you use the sprite of a foot-
  2240.                ball player ten times, it is quite normal to use the same dis-
  2241.                play mode for all ten players!), if you really must use a sprite
  2242.                with two different display methods at the same time, you can use
  2243.                the following trick: load the sprite's data a second time into
  2244.                memory, using a different spriteLOADnumber. For this second
  2245.                copy, you can use another display mode.
  2246.              - Possible ERROR-values returned are: Err_InvalidSpriteNumber and
  2247.                Err_InvalidMode
  2248.  
  2249. See also   : SpriteLoadNumber, SpriteNumber, Display methods, GetModeByte
  2250.  
  2251.  
  2252. SetShadowTab - procedure
  2253. ────────────────────────
  2254.  
  2255. Function   : Set the amount of shadowing in display mode "Display_SHADOW"
  2256.  
  2257. Declaration: {$F+} PROCEDURE SetShadowTab(brightness:BYTE); {$F-}
  2258.  
  2259. Description: Whenever a sprite is drawn in "Display_SHADOW" mode, ANIVGA must
  2260.              know how much darker these shadow areas should be, compared with
  2261.              the brightness of the original (not-shadowed) colors.
  2262.              These data is held in the table ShadowTab and is set to 70% of
  2263.              the colors original brightness. However, you can use this routine
  2264.              to provide more or less darker shadow areas: "brightness" is the
  2265.              percentage of the colors original brightness which shall remain,
  2266.              e.g.: brightness=0 would mean every shadow is completely black,
  2267.              brightness=100 is the original color as shadow (not darkened at
  2268.              all), brightness=40 will darken every color by 100-40=60%, etc.
  2269.  
  2270. Note (!)   : - This routine takes quite a long time (app. 4s on an 8MHz AT).
  2271.              - The argument will be only approximated: the algorithm computes
  2272.                the 256 color values needed precisely and matches them as close
  2273.                as possible to the 256 default colors of graphic mode $13.
  2274.                Note that the palette registers of the VGA card *won't* be
  2275.                changed at all! ANIVGA still works with the standard VGA palette
  2276.                of the BIOS; what it does is solely creating a color look-up-
  2277.                table!
  2278.              - Possible ERROR-values returned are: Err_InvalidPercentage
  2279.  
  2280. See also   : ShadowTab, Display modes, SetModeByte
  2281.  
  2282.  
  2283. SetSpriteCycle - procedure
  2284. ──────────────────────────
  2285.  
  2286. Function   : Links spriteLOADnumbers together to form a sprite cycle
  2287.  
  2288. Declaration: {$F+} PROCEDURE SetSpriteCycle(nr,len:WORD); {$F-}
  2289.  
  2290. Description: "nr" is the first spriteLOADnumber to be included in the sprite
  2291.              cycle and "len" entries (i.e.: from "nr" to "nr+len-1") should be
  2292.              tied together.
  2293.              The routine will then set the according NextSprite[] entries to
  2294.              build this cycle: nr -> nr+1 -> nr+2 -> ... -> nr+len-1 -> nr
  2295.  
  2296. Note       : - The routine uses spriteLOADnumbers, _not_ sprite numbers!
  2297.              - If you want to link sprite(loadnumber)s which do not have conse-
  2298.                cutive (load)numbers, you must do that by setting NextSprite[]
  2299.                accordingly.
  2300.  
  2301. See also   : Sprite cycles, NextSprite
  2302.  
  2303.  
  2304. ShadowTab - "procedure"
  2305. ───────────────────────
  2306.  
  2307. Function   : Table for translating sprite colors into others
  2308.  
  2309. Declaration: {$F+} PROCEDURE ShadowTab; {$F-}
  2310.  
  2311. Description: If the display mode "Display_SHADOW" is set for a physical sprite,
  2312.              its colors will depend not on the values stored in the sprite it-
  2313.              self, but on the values found on the screen at the place where the
  2314.              sprite shall be drawn: every pixel of the sprite will become dar-
  2315.              kened by substituting its corresponding color against the color
  2316.              stored in this color table.
  2317.              At startup, this table is set to make shadows be approximately 70%
  2318.              the brightness of the original colors, but you can adjust this
  2319.              with the routine SetShadowTab() if this default is not suitable
  2320.              for your application.
  2321.              You can even supply a completely different color table (for
  2322.              special effects?).
  2323.              To do so, define an array "[0..255] of byte" (you can use the pre-
  2324.              defined TYPE ColorTable for this), containing for each color of
  2325.              the standard palette its substitute (e.g. setting array element
  2326.              [8]:=13 would mean: "replace every pixel in the shadow area with
  2327.              color 8 against a pixel with color 13") and overwrite the original
  2328.              color table by issuing the command "MOVE(my_array,@ShadowTab^,256)"
  2329.  
  2330. Note       : - Although this table is declared as a procedure, it really is
  2331.                data, not code; so don't call it!
  2332.              - There can be only _one_ color table and it is only active in
  2333.                display mode "Display_SHADOW".
  2334.  
  2335. See also   : SetShadowTab, Display modes, SetModeByte
  2336.  
  2337.  
  2338. SPRITE, Spritenumbers, Spriteloadnumbers - information
  2339. ──────────────────────────────────────────────────────
  2340.  
  2341. A sprite is the basic data element used in ANIVGA. Technically spoken, it is
  2342. nothing more then a two-dimensional array of bytes which becomes copied to the
  2343. screen positions needed, but it is far more comprehensive to think about it as
  2344. a photograph of a figure which can be pasted to the screen whereever you want.
  2345. To distinguish between different sprites, we use natural numbers, but whenever
  2346. we talk about "sprites", we are somehow inaccurate:
  2347. You should notice that there are two kinds of "sprite numbers" which should
  2348. not be mixed up: one is a spriteLOAD number and represents a handle to the
  2349. (physical) sprite data, while the other (normally termed "sprite number") is
  2350. a logical number to address the sprite data.
  2351. Yet, most often it is clear from the context, which meaning is intended:
  2352. For a simple example: if you are going to animate a soccer team, you would
  2353. need 11 sprites for the player - but they all have the same shape. This means,
  2354. you only have to load one sprite (-> you need 1 spriteLOAD number), but need
  2355. 11 copies of that to move around the screen (-> you need 11 sprite numbers).
  2356. (See section "How ANIVGA works" for more about that)
  2357. You can design sprites with the help of the spritemaker-tool MAKES, by using
  2358. GRAB to capture and convert graphic screens from other graphic applications
  2359. or write your own tools for that (it's really not that difficult you think
  2360. now it would be...).
  2361.  
  2362. See also   : sprite format, How ANIVGA works
  2363.  
  2364.  
  2365. SPRITE CYCLES - information
  2366. ───────────────────────────
  2367.  
  2368. Often, you don't want to have a single picture as sprite, but a sequence of
  2369. them which should loop forever. For example, let's assume that you use a torch
  2370. as an animation object in your application and you want it to have a flickering
  2371. flame.
  2372. You would start to draw 5 (say) pictures, which -repeatedly displayed one after
  2373. another- would make the impression of your flickering torch. But within your
  2374. application, you still want to handle these five different images as one single
  2375. object - namely the sprite "torch".
  2376. To do so, you can use a capability of ANIVGA, called a "sprite cycle": load the
  2377. five images as (physical) sprites and tie their loadnumbers together to form
  2378. that sequence!
  2379. The easiest way to do that would be to load the images with consecutive numbers
  2380. and use the SetSpriteCycle() procedure to form the sprite cycle (see there).
  2381. Note that we are talking about linking spriteLOADnumbers here: when you have
  2382. built such a cycle for your torch and you want to use 10 torches in your
  2383. program, you surely want that each of them behaves the same, that is: they all
  2384. should show a flickering flame by using that sprite cycle.
  2385. For this reason, ANIVGA uses spriteLOADnumbers, so that every instantiation of
  2386. a spriteLOADnumber (i.e.: a SpriteN[]-entry) belonging to a cycle will lead to
  2387. a sprite cycle for this sprite!
  2388. A small detail at last: if you defined a sprite cycle to be a->b->c->a->...,
  2389. and initialized a SpriteN[]-entry to "a", then the first sprite displayed at
  2390. the screen will be "b" instead of "a" - why?
  2391. Well, ANIVGA handles sprite cycles in the Animate() routine and thus has two
  2392. possibilities to update the SpriteN[]-table (by issuing a "SpriteN[] :=
  2393. NextSprite[SpriteN[]]" command): _before_ drawing the sprites or _afterwards_.
  2394. But when it does _after_ drawing the sprites, the sprites displayed on your
  2395. screen (=the old SpriteN[] values before doing the above command) are inconsis-
  2396. tent to the according numbers actually held in the SpriteN[]-table!
  2397. This could lead to problems (e.g.: when you do a HitDetect() after calling
  2398. Animate()). Although this could be circumvented by a special grouping of sub-
  2399. routine calls, it is far more convenient to update the SpriteN[]-table _before_
  2400. drawing the sprites.
  2401. The only drawback with this method is the one stated in the beginning: not the
  2402. SpriteN[]-entry supplied by you will be drawn, but its "successor"
  2403. NextSprite[SpriteN[]]!
  2404. However, most often that won't be that bad and *if* it would, you still could
  2405. compensate for it by using the sprite's predecessor (in the above example, you
  2406. would use "c", as it is the predecessor of "a", to display "a").
  2407.  
  2408.  
  2409. SPRITE FORMAT - information
  2410. ───────────────────────────
  2411.  
  2412. As already said, a sprite is nothing more then a two-dimensional array of bytes
  2413. which becomes copied to the screen positions needed.
  2414. For quick animations, the data should be stored in a format which causes few
  2415. and simple transformation steps when accessing the data, but it is hard to
  2416. keep up with that principle, because the graphic mode used is "planed".
  2417. This means that points are _not_ stored sequentially into the graphics memory,
  2418. but in a rather strange way: every 4 points use the same address, but lie in
  2419. different "bitplanes". To cut it short: clipping and drawing sprites is hell
  2420. therefore (and surely one reason why there are so less tools for this mode)
  2421. and ANIVGA uses a very special format to store a sprite (= *.COD-files):
  2422.  
  2423.       0..1   DW offset to Plane_0_Data (points with x-coord. MOD 4=0)
  2424.       2..3   DW offset to Plane_1_Data (points with x-coord. MOD 4=1)
  2425.       4..5   DW offset to Plane_2_Data (points with x-coord. MOD 4=2)
  2426.       6..7   DW offset to Plane_3_Data (points with x-coord. MOD 4=3)
  2427.       8..9   DW sprite width (DIV 4), rounded up if not dividable by 4
  2428.       10..11 DW sprite height in lines
  2429.       12..15 DB 1,2,4,8      ; constants (translate-table)
  2430.       16..17 DW SpriteLength ; length of this sprite file
  2431.       18..37 DW 10 dup(?)    ; reserved area for future use
  2432.       38..39 DB 'K','R'      ; code for "this is a sprite file"
  2433.       40     DB 1            ; version
  2434.       41     DB 0            ; default display mode (0=Display_NORMAL)
  2435.       42..43 DW offset pointer to left boundary table
  2436.       44..45 DW offset pointer to right boundary table
  2437.       46..47 DW offset pointer to top boundary table
  2438.       48..49 DW offset pointer to bottom boundary table
  2439.       50..SpriteLength-1: boundary- and plane data tables
  2440.  
  2441. (If you should wonder why all pointers are only 16 bit long: the maximal size
  2442.  of one sprite is 64k, so offset pointers are sufficient.
  2443.  Another trick is that ANIVGA loads sprites at segment boundaries; for that,
  2444.  you don't have to distinguish between "relative offsets" and "offset poin-
  2445.  ters": if normalized segment addresses (=offset part is ε [0..15]) are used to
  2446.  address sprites, the offset part is always 0, so the two terms are identical!)
  2447.  
  2448. The Plane_?_Data tables consist of the points of the sprite (1 pixel = 1 byte);
  2449. if the sprite width is 12 pixels (say), then each table would hold 12/4=3 bytes
  2450. for each of the sprite's rows:
  2451. Plane_0_Data = color of pixels 0,4,8 of 1. sprite row
  2452.                color of pixels 0,4,8 of 2. sprite row
  2453.                ...
  2454. Plane_1_Data = ditto, for pixels 1,5,9
  2455. Plane_2_Data = ditto, for pixels 2,6,10
  2456. Plane_3_Data = ditto, for pixels 3,7,11
  2457.  
  2458. The boundary tables hold the outermost positions of the sprite:
  2459.  The left/top/right/bottom boundary table holds the leftmost/topmost/rightmost/
  2460.  bottomost pixel of each row/column/row/column (or 16000/16000/-16000/-16000 if
  2461.  none exists), respectively:
  2462. left boundary table = leftmost pixel coordinate of 1. sprite row  (or 16000)
  2463.                       leftmost pixel coordinate of 2. sprite row  (or 16000)
  2464.                       ...
  2465. Note that each entry in the boundary tables consists of a signed integer!
  2466.  
  2467. Note also that sprites are always stored as the smallest, the figure including
  2468. box (rounded up in the x-direction to the next multiple of 4), but that the
  2469. values of the "superfluous points" stored in the plane tables doesn't matter at
  2470. all (no difference which display mode is used for the sprite!), because ANIVGA
  2471. uses only the bytes of the areas which belong to the _real_ sprite-figure
  2472. (ANIVGA determines this parts by assuming the sprite to be "horizontal convex"
  2473. and uses the boundary tables to compute them).
  2474. (Don't worry if you do not understand these technical details now -- hopefully,
  2475. you won't need them at all).
  2476.  
  2477. See also   : MAKES, Display modes, convex, sprite library
  2478.  
  2479.  
  2480. SPRITE LIBRARY - information
  2481. ────────────────────────────
  2482.  
  2483. Sprite files can be combined to sprite libraries. The main advantage of this is
  2484. that you can reduce the number of files needed for your programs dramatically:
  2485. A normal program will use approximately 20..40 different sprites, so that you
  2486. would have 20..40 files only for your sprites!
  2487. But ANIVGA's routine to load sprites "loadSprite()" is flexible enough to dis-
  2488. tinguish whether the file to be loaded contains one or more sprites and loads
  2489. them all.
  2490. To construct such a "sprite library" (suggested filename extension: .LIB), you
  2491. just use MSDos' COPY-command with the binary option "/B"; for example:
  2492.  
  2493.  COPY /B sprite1.cod+d:\sprites\sprite2.cod+testspr.cod A:\mylib.lib
  2494.  
  2495. would concatenate the three sprites "sprite1.cod", "d:\sprites\sprite2.cod" and
  2496. "testspr.cod" and build the sprite library "A:\mylib.lib".
  2497. You can reverse this process with the UNLIB-utility.
  2498.  
  2499. See also   : UNLIB, sprite format, loadSprite
  2500.  
  2501.  
  2502. SpriteAd - variable
  2503. ───────────────────
  2504.  
  2505. Function   : Store the pointers to the sprites' data
  2506.  
  2507. Declaration: VAR SPRITEAD:ARRAY[0..LoadMAX] OF WORD;
  2508.  
  2509. Description: Whenever you load a (physical) sprite with LOADnumber xxx, ANIVGA
  2510.              stores the sprite's data somewhere in RAM and maintains a pointer
  2511.              which points to the beginning of this data as a handle to access
  2512.              the data: this handle is stored in SpriteAd[xxx] and reflects the
  2513.              segment part of the starting address of the data.
  2514.  
  2515. Note       : Don't change that data directly unless you are absolutel sure what
  2516.              you are doing!
  2517.  
  2518. See also   : LoadSprite, SPRITE, Sprite Format
  2519.  
  2520.  
  2521. SPRITEN, SPRITEX, SPRITEY - tables
  2522. ──────────────────────────────────
  2523.  
  2524. Function   : Hold the values of all sprites to be drawn in the next animation
  2525.              cycle.
  2526.  
  2527. Declaration: VAR SpriteN:ARRAY[0..NMAX] of Integer  (SpriteX/Y dto.)
  2528.  
  2529. Description: ANIVGA is based on tables: in SpriteN[] you must declare, which
  2530.              sprites shall be drawn in the next animation step. To do that,
  2531.              store the spriteLOAD number of the sprites into the SpriteN[]-
  2532.              entries; a zero indicates that the according sprite is inactive
  2533.              and should not be displayed.
  2534.              For every active sprite (SpriteN[i]<>0), a pair of virtual coor-
  2535.              dinates in the range -16000..+16000 must be specified in the
  2536.              SpriteX[i] and SpriteY[i] entries to determine the sprites' po-
  2537.              sition on the (virtual) screen.
  2538.              These coordinates will be transformed internally into real coor-
  2539.              dinates to decide whether the sprite is onscreen and has to be
  2540.              displayed or not.
  2541.  
  2542. Note       : If you have less sprites than are allowed by the system (that is:
  2543.              less than NMAX+1), your decision what table entries you use are
  2544.              arbitrary; if for example you have only two sprites, it won't
  2545.              matter, if you use SpriteN[0] for the first one and SpriteN[1]
  2546.              for the other or vice versa, or SpriteN[123] and SpriteN[310] or
  2547.              whatever valid indices you can think of - except in one point:
  2548.              the sprites are drawn in reverse order, that means SpriteN[NMAX]
  2549.              is drawn first, then SpriteN[NMAX-1] ... SpriteN[0].
  2550.              For that, if two (or more) sprites overlap each other, the one
  2551.              with the smallest index is drawn topmost and covers the other(s).
  2552.  
  2553.              For performance reasons you should observe another rule: if you
  2554.              use different display methods for different sprites then try to
  2555.              group your sprites in such a way, that sprites with the same dis-
  2556.              play method have continous indices. As an example: if the sprites
  2557.              with (load)number 1 use one method and the ones with number 2
  2558.              another, then the sequence SpriteN[]=(...2,2,2,2,2,...,1,1,1...)
  2559.              would be better than (...2,2,1,2,...,1,2,...,1,2,...).
  2560.              This is due to the fact that whenever ANIVGA has to draw a sprite
  2561.              with a display method other than the active one, it must inter-
  2562.              nally switch from one method to the other which costs some time.
  2563.  
  2564. See also   : SetModeByte
  2565.  
  2566.  
  2567. StartVirtualX, StartVirtualY - variables
  2568. ────────────────────────────────────────
  2569.  
  2570. Function   : Specify the upper left corner of the visible world
  2571.  
  2572. Declaration: CONST StartVirtualX:INTEGER=0;
  2573.                    StartVirtualY:INTEGER=0;
  2574.  
  2575. Description: When working with virtual coordinates, your screen displays only a
  2576.              very small window (320x200 points) of this "virtual screen"
  2577.              (32000x32000 points). To tell ANIVGA which part of this virtual
  2578.              screen is to be displayed, you specify the upper left corner of
  2579.              the visible part in (StartVirtualX,StartVirtualY).
  2580.              For example, setting (StartVirtualX,StartVirtualY) to (100,1000)
  2581.              would define that the part of the virtual screen having x-coordi-
  2582.              nates ε [100..100+XMAX] and y-coordinates ε [1000..1000+YMAX] to
  2583.              be displayed.
  2584.  
  2585. Note       : Setting these variables doesn't affect the HitDetect-function: if
  2586.              two sprites collide outside the visible area, it will be detected,
  2587.              still.
  2588.  
  2589. See also   : coordinates
  2590.  
  2591.  
  2592. Table - TYPE
  2593. ────────────
  2594.  
  2595. Function   : Supply a data type for the animation variables
  2596.  
  2597. Declaration: TYPE Table=ARRAY[0..NMAX] OF INTEGER;
  2598.  
  2599. Description: A lot of variables in ANIVGA have to be of type "one entry for
  2600.              each sprite" and "Table" is the appropriate form for that.
  2601.  
  2602. Note       : -
  2603.  
  2604. See also   : SpriteX, SpriteY, SpriteN
  2605.  
  2606.  
  2607. Tile - information
  2608. ──────────────────
  2609.  
  2610. "Tiles" are graphic images, 16 pixels wide and high. They are used to define a
  2611. scrollable background image when you use SCROLLING as background mode.
  2612. Due to memory limitations, it is impossible to hold a complete background image
  2613. in memory (because virtual coordinates range 32000 pixels in x/y-directions,
  2614. one would need app. 977 MB (!) RAM for that).
  2615. Instead, you may define up to 256 different tiles and then combine them to form
  2616. the graphic background, which may consist of up to MaxTiles (=10000) tiles
  2617. (using the 256 different tiles).
  2618. (A simple example for that can be found by "Background").
  2619. ANIVGA stores tiles in a slightly different format then sprites internally, but
  2620. you don't have to bother your head about that: on disk, tiles have the same
  2621. format as sprites, so you can use all the utility programs to create/edit
  2622. sprites also to create/edit tiles! The only restriction you have to care about
  2623. is, that a tile has the definite size of 16 pixels in each direction (but see
  2624. the LoadTile()-function for some simplifications about even that).
  2625.  
  2626. See also   : Background, LoadTile
  2627.  
  2628.  
  2629. UNLIB - utility
  2630. ───────────────
  2631.  
  2632. Sometimes, you will want to reverse the process of building a sprite library,
  2633. that is: you want to split a sprite library into the sprite files of which it
  2634. consists.
  2635. To do that, call UNLIB with the name of the sprite library to split. UNLIB will
  2636. then create the files UNLIB000.COD, UNLIB001.COD, UNLIB002.COD,...  which re-
  2637. present the sprite files wanted.
  2638. Note here that UNLIB cannot restore the original filenames you used (there is
  2639. no such entry in a sprite's header). For that, it is a good idea to write down
  2640. the names and sequence of the sprite files used in building a sprite library.
  2641. (If you didn't, you still can load every extracted sprite with MAKES, look at
  2642.  it and give it the right name then)
  2643.  
  2644. See also   : sprite library, MAKES, sprite format
  2645.  
  2646.  
  2647. VIRTUAL COORDINATES - information
  2648. ─────────────────────────────────
  2649.  
  2650. See        : coordinates
  2651.  
  2652.  
  2653. WriteBackgroundPage - procedure
  2654. ───────────────────────────────
  2655.  
  2656. Function   : Saves the background image to disk
  2657.  
  2658. Declaration: {$F+} PROCEDURE WriteBackgroundPage(name:STRING); {$F-}
  2659.  
  2660. Description: This is merely a shortcut of the WritePage()-procedure (see
  2661.              there), i.e. WritePage(name; BACKGNDPAGE) would do an equivalent
  2662.              job.
  2663.  
  2664. Note       : Possible ERROR-values returned are Err_FileIO
  2665.  
  2666. See also   : WritePage
  2667.  
  2668.  
  2669. WritePage - procedure
  2670. ─────────────────────
  2671.  
  2672. Function   : Saves a graphic page to disk
  2673.  
  2674. Declaration: {$F+} PROCEDURE WritePage(name:STRING; pa:BYTE); {$F-}
  2675.  
  2676. Description: To save an image of one of the drawing pages (0 or 1) or the back-
  2677.              groundpage BACKGNDPAGE (=2), specify the approriate page number in
  2678.              "pa" and a valid MSDOS-path/name where to store the data in
  2679.              "name".
  2680.  
  2681. Note       : - Make sure that your disk has enough space to hold the data: one
  2682.                page is stored as 64003 bytes!
  2683.              - You can't use this procedure for saving the background page "pa"
  2684.                =SCROLLPAGE in background mode SCROLLING!
  2685.              - Possible ERROR-values returned are: Err_InvalidPageNumber and
  2686.                Err_FileIO
  2687.  
  2688. See also   : WriteBackgroundPage, LoadPage
  2689.  
  2690.  
  2691. XMAX - constant
  2692. ───────────────
  2693.  
  2694. Function   : Specifies the maximal absolute x-coordinate
  2695.  
  2696. Declaration: CONST XMAX=319
  2697.  
  2698. Description: XMAX is the biggest _absolute_ coordinate in the x-direction which
  2699.              can be used: all x-coordinates must lie in the range 0..XMAX.
  2700.  
  2701. Note       : Probably, you will never use this constant at all, because nearly
  2702.              everything in ANIVGA's user interface works with _virtual_ coordi-
  2703.              nates, but who knows...
  2704.  
  2705. See also   : YMAX, coordinates
  2706.  
  2707.  
  2708. XTiles - variable
  2709. ─────────────────
  2710.  
  2711. Function   : Holds the width of the scrollable background image in tiles
  2712.  
  2713. Declaration: VAR XTiles:INTEGER;
  2714.  
  2715. Description: When using background mode SCROLLING, you have to specify the size
  2716.          of your scrolling background area (with the SetBackgroundScroll-
  2717.          Range()-procedure). ANIVGA adjusts these values slightly and
  2718.          computes the size of the resulting background image in tiles.
  2719.          The width of this area (in tiles) is then stored in XTiles.
  2720.  
  2721. Notes       : Don't change this variable directly!
  2722.  
  2723. See also   : YTiles, Background, SetBackgroundScrollRange
  2724.  
  2725.  
  2726. YMAX - constant
  2727. ───────────────
  2728.  
  2729. Function   : Specifies the maximal absolute y-coordinate
  2730.  
  2731. Declaration: CONST YMAX=199
  2732.  
  2733. Description: YMAX is the biggest _absolute_ y-coordinate which may be used,
  2734.              that is, every y-coordinate must lie in the range 0..YMAX.
  2735.  
  2736. Note       : Probably, you will never use this constant at all, because nearly
  2737.              everything in ANIVGA's user interface works with _virtual_ coordi-
  2738.              nates, but who knows...
  2739.  
  2740. See also   : XMAX, coordinates
  2741.  
  2742.  
  2743. YTiles - variable
  2744. ─────────────────
  2745.  
  2746. Function   : Holds the height of the scrollable background image in tiles
  2747.  
  2748. Declaration: VAR YTiles:INTEGER;
  2749.  
  2750. Description: When using background mode SCROLLING, you have to specify the size
  2751.          of your scrolling background area (with the SetBackgroundScroll-
  2752.          Range()-procedure). ANIVGA adjusts these values slightly and
  2753.          computes the size of the resulting background image in tiles.
  2754.          The heigh of this area (in tiles) is then stored in YTiles.
  2755.  
  2756. Notes       : Don't change this variable directly!
  2757.  
  2758. See also   : XTiles, Background, SetBackgroundScrollRange
  2759.